MongoDB 查询,按组分组并计算每个元素的数量,搜索文档内的数组元素。

3
假设我有一个具有以下结构的包含多个文档的集合:
{
  _id: "id12345",
  objects: ["123","456", "789"]
}

现在我想创建一个查询,其中我传递一个对象数组,并获取每个元素在文档中出现的计数,类似于这样:
查询输入:["123","321"] 输出结果:
{
  "123": 1,
  "321": 0
}

我希望只需一个查询即可完成此操作,传递一个数组。我知道我可以一个一个地轻松完成,而不是使用数组,但这不是目的。
2个回答

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"}}

嗨@Veeram,感谢您的答案,它按预期工作。我需要使用Spring Data MongoDB实现这个功能,我知道“Aggregation” Spring操作可以实现,但是我在$map操作方面遇到了一些问题,使用Spring的“mapItemsOf”函数。您能给我一个想法,应该如何实现吗? - Luis Miguel
不用谢。我认为你不能使用 mapItemsOf,因为它只接受字段引用或聚合表达式,而不是静态数组。你需要准备聚合表达式。类似这样的东西:project().and(new AggregationExpression() { @Override public Document toDocument(AggregationOperationContext aggregationOperationContext) { $map code here } }).as("keyandcount") - s7vr
你可以使用这里的示例,并根据自己的需求进行调整。 - s7vr

0
通常获取此内容的查询非常简单,因为不建议在数据层中将值切换为键,而是更多地在表示层中进行。
db.collection.aggregate([
  {
    $unwind: "$objects"
  },
  {
    $group: {
      _id: "$objects",
      count: {
        $sum: 1
      }
    }
  }
])

会给你数字作为_id和一个count字段,其中包含出现次数。然后您可以在应用程序中对其进行处理,使其看起来任何您想要的样子。

这里是结果的简单示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接