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()"}
另外要小心,不要碰到保留字和其他陷阱。
请仔细阅读此操作员的文档,并确保您绝对需要它。 它会减慢相当多的事情,因为你发现将扫描整个集合。 它不能使用索引。