13

在我的收藏中,每个文档都有 2 个日期,已修改和同步。我想找到那些修改过的>同步,或者同步不存在。

我试过了

{'modified': { $gt : 'sync' }}

但它没有显示我的预期。有任何想法吗?

谢谢

4

6 回答 6

17

您不能将一个字段与另一个字段的值进行正常查询匹配。但是,您可以使用聚合框架执行此操作:

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.

于 2013-08-07T16:34:49.903 回答
10

对于 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“保留”逻辑条件为真的文档或$$PRUNE“删除”条件为真的文档错误的。

考虑运行以下展示上述概念的聚合操作:

db.test.aggregate([
    { "$redact": {
        "$cond": [
            { "$gt": ["$modified", "$sync"] },
            "$$KEEP",
            "$$PRUNE"
        ]
    } }
])

此操作类似于拥有一个$project管道,该管道选择集合中的字段并创建一个新字段,该字段保存逻辑条件查询的结果,然后是后续的$match,除了$redact使用更有效的单个管道阶段:

于 2018-03-15T19:54:14.347 回答
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"})
> 
于 2016-07-04T13:22:28.113 回答
0

使用 Javascript,使用 foreach 并将 Date 转换为 toDateString()

db.ledgers.find({}).forEach(function(item){

    if(item.fromdate.toDateString() == item.todate.toDateString())
    {
        printjson(item)
    }
})
于 2017-06-09T05:14:57.310 回答
-1

现在您的查询正在尝试返回所有结果,使得该modified字段大于 word 'sync'。试着去掉周围的引号sync,看看是否能解决任何问题。否则,我做了一些研究,发现了这个问题。您尝试做的事情可能无法在单个查询中完成,但是一旦您从数据库中提取所有内容,您就应该能够操作您的数据。

于 2013-08-07T16:25:25.813 回答
-1

要在不聚合的情况下解决此问题,请将您的查询更改为: {'modified': { $gt : ISODate(this.sync) }}

于 2015-06-24T02:21:36.363 回答