Mongodb查询,通过对每个元素进行计数并对其进行计数来搜索文档内部的数组元素

时间:2018-08-21 03:37:35

标签: java mongodb aggregation-framework

假设我有一个包含多个具有以下结构的文档的集合:

{
  _id: "id12345",
  objects: ["123","456", "789"]
}

现在,我想创建一个查询,在该查询中我传递一个对象数组,并获取该数组中每个元素在文档中的出现次数,如下所示:

查询输入:["123","321"] 输出:

{
  "123": 1,
  "321": 0
}

我只想通过传递一个数组的一个查询来执行此操作,我知道我可以轻松地一个接一个地而不是一个数组地执行此操作,但这不是目的。

2 个答案:

答案 0 :(得分:1)

您可以在3.6中使用以下汇总。

$match过滤输入数组和对象数组之间至少有一个数组匹配的文档。

$project$map迭代输入数组,并与对象数组中的每个数组元素进行比较,并根据匹配结果返回0和1。

$unwind$group,以计算所有文档中数组元素的出现。

db.colname.aggregate([
 {"$match":{"objects":{"$in":["123","321"]}}},
 {"$project":{
   "keyandcount":{
     "$map":{
       "input":["123","321"],
       "in":{
         "k":"$$this",
         "v":{"$cond":[{"$in":["$$this","$objects"]},1,0]}
       }
     }
   }
 }},
 {"$unwind":"$keyandcount"},
 {"$group":{"_id":"$keyandcount.k","count":{"$sum":"$keyandcount.v"}}}
])

您可以在最后两个阶段添加以下内容,以格式化对键值对的响应。

{"$group":{_id: null,"keycountpair":{"$mergeObjects":{"$arrayToObject":[[["$_id","$count"]]]}}}},
{"$replaceRoot":{"newRoot":"$keycountpair"}}

答案 1 :(得分:0)

通常,获取此信息的查询非常简单,因为不建议在数据层中将值切换为键,而在表示层中将其切换为键。

所以这个:

db.collection.aggregate([
  {
    $unwind: "$objects"
  },
  {
    $group: {
      _id: "$objects",
      count: {
        $sum: 1
      }
    }
  }
])

将为您提供数字_id和一个count字段以及出现次数。然后,您可以在自己的应用程序中对其进行按摩,使其以您想要的方式呈现。

Here is a simple example of the result