我有一个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"
}
日期是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"});
我做错了什么? 谢谢!!
--- ---- EDIT
所以我尝试使用如下的小数据进行测试:
> 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")
}
您无法使用日期,因为您可以看到:
> 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")
}
适用于字符串值:
> db.myCollection.find({$where: "this.title == this.description"},{ _id: 0, title: 1 });
{ "title" : "samedescription" }
答案 0 :(得分:1)
在比较JavaScript中的日期时,您必须非常小心 - 使用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)"});
这不起作用,因为您在初始化日期时没有使用new
。这通常具有欢闹的结果,所有日期彼此相等:
> Date(2014,2,8) == Date(1941,12,7)
true
> Date(2000,1,1) == Date(1995,2,8)
true
但即使您使用new
正确地实例化日期,在使用==
比较日期时仍会获得热闹的结果,如gist所示:
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)
至于你的其他疑问:
如果我将它们视为字符串,它就无效了:
db.myCollection.find({$ where:“this.start_date == this.end_date”});
您实际上并没有将它们作为字符串进行比较,而是在比较ISODate
个对象,这就是它们的存储方式。对于ISODate
,类似于Date
,==
运算符将返回false,除非您要比较完全相同的实例。但是,使用getTime
应该可行,这就是我上面所做的。
希望这一切都没有任何意义,因为如果确实如此,我会担心你的理智。
答案 1 :(得分:0)
- 编辑 -
您正在寻找$where运营商。您的查询必须使用有效的JSON表示法,并且在此运算符之外,没有其他访问权限的原始JavaScript表示法。
最后:
{$where: "this.start_date.valueOf() == this.end_date.valueOf()"}
另外注意不要碰到保留字和其他陷阱。
非常小心阅读有关此运算符的文档,并确保您绝对需要它。由于您的查找将扫描整个集合,因此将大大减慢速度。 无法使用索引。