在我的收藏中,每个文档都有2个日期,经过修改和同步。我想找到那些经过修改的>同步或同步不存在。
我试过
{'modified': { $gt : 'sync' }}
但它没有显示出我的预期。有什么想法吗?
由于
答案 0 :(得分:18)
您无法将字段与另一个字段的值与普通查询匹配进行比较。但是,您可以使用聚合框架执行此操作:
db.so.aggregate( [
{ $match: …your normal other query… },
{ $match: { $eq: [ '$modified', '$sync' ] } }
] );
我把......你正常的其他查询...放在那里,因为你可以使用该索引。因此,如果您只想对name
字段为charles
的文档执行此操作,则可以执行以下操作:
db.so.ensureIndex( { name: 1 } );
db.so.aggregate( [
{ $match: { name: 'charles' } },
{ $project: {
modified: 1,
sync: 1,
name: 1,
eq: { $cond: [ { $gt: [ '$modified', '$sync' ] }, 1, 0 ] }
} },
{ $match: { eq: 1 } }
] );
输入:
{ "_id" : ObjectId("520276459bf0f0f3a6e4589c"), "modified" : 73845345, "sync" : 73234 }
{ "_id" : ObjectId("5202764f9bf0f0f3a6e4589d"), "modified" : 4, "sync" : 4 }
{ "_id" : ObjectId("5202765b9bf0f0f3a6e4589e"), "modified" : 4, "sync" : 4, "name" : "charles" }
{ "_id" : ObjectId("5202765e9bf0f0f3a6e4589f"), "modified" : 4, "sync" : 45, "name" : "charles" }
{ "_id" : ObjectId("520276949bf0f0f3a6e458a1"), "modified" : 46, "sync" : 45, "name" : "charles" }
返回:
{
"result" : [
{
"_id" : ObjectId("520276949bf0f0f3a6e458a1"),
"modified" : 46,
"sync" : 45,
"name" : "charles",
"eq" : 1
}
],
"ok" : 1
}
如果您还需要其他字段,则需要在$project
。
答案 1 :(得分:3)
简单地
db.collection.find({$where:"this.modified>this.sync"})
实施例
Kobkrits-MacBook-Pro-2:~ kobkrit$ mongo
MongoDB shell version: 3.2.3
connecting to: test
> db.time.insert({d1:new Date(), d2: new Date(new Date().getTime()+10000)})
WriteResult({ "nInserted" : 1 })
> db.time.find()
{ "_id" : ObjectId("577a619493653ac93093883f"), "d1" : ISODate("2016-07-04T13:16:04.167Z"), "d2" : ISODate("2016-07-04T13:16:14.167Z") }
> db.time.find({$where:"this.d1<this.d2"})
{ "_id" : ObjectId("577a619493653ac93093883f"), "d1" : ISODate("2016-07-04T13:16:04.167Z"), "d2" : ISODate("2016-07-04T13:16:14.167Z") }
> db.time.find({$where:"this.d1>this.d2"})
> db.time.find({$where:"this.d1==this.d2"})
>
答案 2 :(得分:2)
对于MongoDB 3.6及更高版本:
$expr
运算符允许在查询语言中使用聚合表达式,因此您可以执行以下操作:
db.test.find({ "$expr": { "$gt": ["$modified", "$sync"] } })
或使用聚合框架与 $match
管道
db.test.aggregate([
{ "$match": { "$expr": { "$gt": ["$modified", "$sync"] } } }
])
对于MongoDB 3.0 +:
您还可以将聚合框架与 $redact
管道运算符一起使用,该运算符允许您使用 $cond
运算符处理逻辑条件,使用特殊操作 $$KEEP
来&#34;保持&#34;逻辑条件为真的文档或 $$PRUNE
到&#34;删除&#34;条件错误的文件。
考虑运行以下聚合操作,该操作演示了上述概念:
db.test.aggregate([
{ "$redact": {
"$cond": [
{ "$gt": ["$modified", "$sync"] },
"$$KEEP",
"$$PRUNE"
]
} }
])
此操作类似于具有 $project
管道,该管道选择集合中的字段并创建一个新字段,其中包含逻辑条件查询的结果,然后是后续的 $match
,但 $redact
使用更高效的单个管道阶段:
答案 3 :(得分:0)
使用Javascript,使用foreach并将Date转换为toDateString()
db.ledgers.find({}).forEach(function(item){
if(item.fromdate.toDateString() == item.todate.toDateString())
{
printjson(item)
}
})
答案 4 :(得分:-1)
现在,您的查询尝试返回所有结果,以使modified
字段大于单词'sync'
。尝试删除sync
周围的引号,看看是否有任何修复。否则,我做了一点研究,发现this question。您在单个查询中可能无法实现的目标,但是一旦从数据库中提取所有内容,您就应该能够操作数据。
答案 5 :(得分:-1)
要修复此问题而不进行聚合,请将查询更改为:
{'modified': { $gt : ISODate(this.sync) }}