【问题标题】:Mongodb: find documents with array field that contains more than one SAME specified valueMongodb:查找包含多个相同指定值的数组字段的文档
【发布时间】:2015-04-14 07:50:38
【问题描述】:

collection test 一共有三个文件:

// document 1
{
    "id": 1,
    "score": [3,2,5,4,5]
}

// document 2
{
    "id": 2,
    "score": [5,5]
}

// document 3
{
    "id": 3,
    "score": [5,3,3]
}

我想获取 score 字段包含 [5,5] 的文档。

查询:

db.test.find( {"score": {"$all": [5,5]}} )

将返回文档 1、2 和 3,但我只想获取文档 1 和 2。

我该怎么做?

【问题讨论】:

  • 请您澄清您的预期结果 - 您声明“我想获取分数字段包含 [5,5] 的文档” - 您拥有的唯一文档 [5,5] 是文档 2。但是你接着说“只想获取文档 1 和 2”。
  • 对不起我的例外结果是:文档至少有两个“5”分数
  • 这样的话,请看下面我的回答
  • 我的错,我的意思是我想获取 score 字段至少包含两个“5”的文档。所以我想获取文档 1 和 2。

标签: mongodb


【解决方案1】:

阅读您的问题后,我个人认为 mongodb 尚不支持这种查询。如果有人知道如何使用 mongo 查询找到此问题,他们会在这里发布答案。

但我认为这可以使用 mongo forEach 方法,所以下面的代码将符合您的条件

    db.collectionName.find().forEach(function(myDoc) {
    var scoreCounts = {};
    var arr = myDoc.score;
    for (var i = 0; i < arr.length; i++) {
    var num = arr[i];
    scoreCounts[num] = scoreCounts[num] ? scoreCounts[num] + 1 : 1;
    }
    if (scoreCounts[5] >= 2) { //scoreCounts[5] this find occurrence of 5  
    printjsononeline(myDoc);
    }
    });

【讨论】:

  • 谢谢!我已经阅读了半天的 mongodb 手册,几乎可以确保 mongodb 不支持它。正如你所说,对我来说最好的方法是通过编程过滤结果。
【解决方案2】:

在 2.6 版中更改。

$all 相当于对指定值进行$and 操作;即以下语句:

{ tags: { $all: [ "ssl" , "security" ] } } 相当于:

{ $and: [ { tags: "ssl" }, { tags: "security" } ] }

认为你需要传入一个嵌套数组 -

那就试试吧

db.test.find( {"score": {"$all": [[5,5]]}} )

来源

在 2.6 版中更改。

当传递嵌套数组的数组时(例如 [ [ "A" ] ] ),$all 现在可以匹配字段包含嵌套数组作为元素的文档(例如 field: [ [ "A" ], . .. ]),或者字段等于嵌套数组(例如字段:[“A”])。

http://docs.mongodb.org/manual/reference/operator/query/all/

【讨论】:

  • 您的查询仅返回匹配的文档 2,但预期的输出也是文档 1 和 2。而且只有({"score":[5,5]})返回文档2也不需要嵌套数组
  • OP 状态 - “我想获取 score 字段包含 [5,5] 的文档” - 然后进入状态“但我只想获取文档 1 和 2” - 模棱两可。跨度>
  • 但 OP 状态也提到了return document 1, 2 and 3, but I only want to fetch document 1 and 2
  • 我测试了这个查询,只返回了文档2。我认为这个查询与db.test.find( {"score": [5,5]} )相同
【解决方案3】:

您可以通过聚合来做到这一点。第一步可以在{ "score" : 1 } 上使用索引,但其余的工作很辛苦。

db.test.aggregate([
    { "$match" : { "score" : 5 } },
    { "$unwind" : "$score" },
    { "$match" : { "score" : 5 } },
    { "$group" : { "_id" : "$_id", "sz" : { "$sum" : 1 } } }, // use $first here to include other fields in the results
    { "$match" : { "sz" : { "$gte" : 2 } } }
])

【讨论】:

  • 谢谢!真是辛苦了……在我的实际使用场景中,我想通过任意分数来查询文档,比如: * 分数包含 2 和 3 的文档 * 分数包含 5 的文档 * 分数包含至少两个 5 和很快。第一个和第二个查询很容易做到,但是第三个查询是我的问题。我想找到一种通用(且简单)的方法来做到这一点,但这似乎是不可能的......
猜你喜欢
  • 2023-03-21
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 2016-06-18
相关资源
最近更新 更多