【问题标题】:Find MongoDB documents by subdocument size按子文档大小查找 MongoDB 文档
【发布时间】:2015-05-03 10:37:38
【问题描述】:

我有一个包含如下文档的集合:

{
    "_id" : ObjectId("..."),
    "some_key" : "some_value",
    ...,
    "another_key" : {
        "a key" : "a value",
        ...
    }
}

这个集合中有几种不同类型的文档,最大的不同发生在“another_key”字段中。

我希望能够根据“another_key”中子文档的大小来查找文档。如果它是一个数组,我可以使用这个查询:

{
    "another_key" : {
        $size : 0
    }
}

查找所有留空的文档。不幸的是,根据the documentation,这只适用于数组。

有没有办法对子文档执行此操作?

【问题讨论】:

  • 嵌套对象并不是真正的子文档,因此不应被称为子文档,因为它们不像文档,也不能在它们上使用 $ 运算符。我建议将 another_key 变成一个对象数组(子文档),如下所示:{key: 'akey, value: 'avalue'}。您现在可以找到 $size,如果需要,还可以找到密钥。 db.collection.find({'another_key.key': 'aKey}) 等
  • 您能详细解释一下这个用例吗?老实说,想做这样的事情很奇怪,我想知道总体目标是什么。也许有更好的方法?使用$where 通常是一个非常糟糕的主意。
  • @wdberkeley 我的特殊用例是我正在使用其他人提供的数据,并且我想编写一个脚本来验证他们的代码更新时数据不会被弄乱.就我而言,我可以检查它是否为空,但我想知道更普遍的问题。
  • @BrianNoah 你应该把它写成完整的答案。它不适用于我的情况,因为我不是创建数据的人,但它可以帮助其他人。

标签: mongodb mongodb-query


【解决方案1】:

使用Object.keys 获取子文档键和$where 运算符。

db.collection.find( { 
    'timestamp': "your value",
    '$where': function() { return Object.keys(this.another_key).length === 0; } 
})

【讨论】:

  • $where 的性能不是很好,并且在大型集合上会非常慢。
【解决方案2】:

嵌套对象并不是真正的子文档,我也不将它们称为子文档,因为它们不像文档,并且不能在它们上使用$ 运算符。索引对它们也不起作用,但是我们可以索引“another_key.key”以获得更好的搜索性能。

我建议将another_key 变成一个对象数组(子文档),如下所示:

db.items.insert({
    some_key : 'some_value',
    another_key : [
        {key: 'akey', value: 'avalue'},
        {key: 'bkey', value: 'bvalue'}
    ]
});

您现在可以按 $size 和键查找。

mongos> db.items.find({another_key: {$size: 0}})
 // 0 documents
mongos> db.items.find({another_key: {$size: 1}})
 // 0 documents
mongos> db.items.find({another_key: {$size: 2}})
 { "_id" : ObjectId("54f62a48e2fdcc95d4934424"), "some_key" : "some_value", "another_key" : [ { "key" : "akey", "value" : "avalue" }, { "key" : "bkey", "value" : "bvalue" } ] }
mongos> db.items.find({another_key: {$size: 3}})
 // 0 documents

mongos> db.collection.find({'another_key.key': 'akey'})
 { "_id" : ObjectId("54f62a48e2fdcc95d4934424"), "some_key" : "some_value", "another_key" : [ { "key" : "akey", "value" : "avalue" }, { "key" : "bkey", "value" : "bvalue" } ] }

很遗憾,您无法进行比较 $size 查询:

mongos> db.items.find({another_key: {$size: {$gt:1} } } )
 error: {
     "$err" : "Can't canonicalize query: BadValue $size needs a number",
     "code" : 17287
 }

【讨论】:

    猜你喜欢
    • 2021-07-05
    • 2013-06-01
    • 1970-01-01
    • 2017-04-15
    • 2021-07-25
    • 2016-08-25
    • 2016-04-18
    • 1970-01-01
    • 2015-07-08
    相关资源
    最近更新 更多