MongoDB:查找两个指定键值相等的项目

我有一个mongoDB集合,集合中的一个项目如下所示:

{ "_id": "52f535b56268a019bd11cc2a", "description": "Some description", "entry_date": "2014-02-07T19:36:21.430Z", "last_update": "2014-02-07T19:36:21.430Z", "r": "samestring", "s": "samestring" } 

date是ISODate对象。

这个查询返回正确的项目

 db.myCollection.find({$where : "this.entry_date < this.last_update"}); 

下面的查询返回什么(我期望它返回上述项目):

 db.myCollection.find({$where : "this.entry_date == this.last_update"}); 

和这个查询返回所有项目(我期望它再次返回上述项目):

  db.myCollection.find({$where :"this.r == this.s"}); 

我究竟做错了什么? 谢谢!!

– -编辑 – –

所以我试着用如下的小数据进行testing:

 > db.myCollection.find({},{ _id: 0, start_date: 1, end_date: 1}); { "start_date" : ISODate("2014-02-07T19:36:21.430Z"), "end_date" : ISODate("2014-02-07T19:36:21.430Z") } { "start_date" : ISODate("2014-02-07T19:36:21.430Z"), "end_date" : ISODate("2014-02-07T22:39:02.114Z") } 

它不适用于date,你可以看到:

 > db.myCollection.find( {$where: "Date(this.start_date) == Date(this.end_date)"}, { _id: 0, start_date: 1, end_date: 1 } ); { "start_date" : ISODate("2014-02-07T19:36:21.430Z"), "end_date" : ISODate("2014-02-07T19:36:21.430Z") } { "start_date" : ISODate("2014-02-07T19:36:21.430Z"), "end_date" : ISODate("2014-02-07T22:39:02.114Z") } 

适用于string值:

 > db.myCollection.find({$where: "this.title == this.description"},{ _id: 0, title: 1 }); { "title" : "samedescription" } 

比较JavaScript中的date时必须非常小心 – 使用valueOf()getTime()

 > db.myCollection.find({$where: "this.start_date.getTime() == this.end_date.getTime()"}); { "_id" : ObjectId("52f5b7e316d795f0a076fbdf"), "description" : "a description", "title" : "a title", "start_date" : ISODate("2014-02-07T19:36:21.430Z"), "end_date" : ISODate("2014-02-07T19:36:21.430Z") } 

这就是为什么你的其他查询不起作用。

 db.myCollection.find({$where: "Date(this.start_date) == Date(this.end_date)"}); 

这不起作用,因为您在初始化date时没有使用new的。 一般而言,所有的date都是相等的:

 > Date(2014,2,8) == Date(1941,12,7) true > Date(2000,1,1) == Date(1995,2,8) true 

但是,即使你使用new正确地实例化date,当使用==比较date时,你仍然会得到令人愉快的结果,正如在这个要点中所演示的那样:

 var dateValue = 504001800000; // Saturday, December 21st, 1985 at 3:30am EST var date1 = new Date(dateValue); var date2 = new Date(dateValue); console.log(date1 == date2); // false (different instances) console.log(date1 === date2); // false (different instances) console.log(date1 > date2); // false (date1 is not later than date2) console.log(date1 < date2); // false (date1 is not earlier than date2) console.log(date1 >= date2); // true (rofl) console.log(date1 <= date2); // true (ahahahaha) 

至于你的其他查询:

如果我认为它们是string,它也不起作用:

db.myCollection.find({$ where:“this.start_date == this.end_date”});

你实际上并没有将它们比作string,而是比较ISODate对象,这是它们如何存储的。 对于ISODate ,与Date类似, ==运算符将返回false,除非您正在比较完全相同的实例。 使用getTime应该可以,但是,这正是我上面所做的。

希望这些没有任何意义,因为如果这样做,我担心你的理智。

–EDITED–

您正在寻找$ where操作符。 您的查询必须使用有效的JSON表示法,并且在此运算符之外,没有其他方法可以访问这种原始JavaScript表示法。

date

最后:

 {$where: "this.start_date.valueOf() == this.end_date.valueOf()"} 

另外要小心,不要碰到保留字和其他陷阱。

请仔细阅读此操作员的文档,并确保您绝对需要它。 它减慢相当多的事情,因为你发现将扫描整个集合。 它不能使用索引。