gpt4 book ai didi

mongodb - 聚合计数数组成员匹配条件

转载 作者:可可西里 更新时间:2023-11-01 09:14:45 47 4
gpt4 key购买 nike

如标题所述,我在使用 MongoDB 计算数组中的元素时遇到了一些麻烦。我有一个只有一个文档的数据库,制作如下:

 {_id: ObjectId("abcdefghilmnopq"),
"Array": [
{field1: "val1",
field2: "val2",
field3: "val3",
...
},
{field1: "Value1",
field2: "Value2",
field3: "Value3",
...
},
...
]
}

我想计算数组中具有特定条件的元素的数量(例如 field1: "a",并计算所有具有 field1 = a 的元素) .我正在尝试使用这段代码:

db.collection.aggregate([
{ $unwind : {path: "$Array",
includeArrayIndex: "arrayIndex"}},
{ $match : { "Array.field1" : "a"}},
{ $project : { _id : 0,
Array : 1,
arrayIndex: 1,
total: {$size: "$Array"}}}
])

但我收到此错误:

Command failed with error 17124: 'The argument to $size must be anarray, but was of type: object' on server

我寻找了这个问题的几个答案,但我没有找到任何解决我的问题的方法。我的意思是,“数组”是一个数组!

最佳答案

错误是因为它在你之后不再是数组 $unwind 因此不再是 $size 的有效参数.

您似乎试图“合并”几个现有的答案,但不了解它们在做什么。你真正想要的是 $filter $size

db.collection.aggregate([
{ "$project": {
"total": {
"$size": {
"$filter": {
"input": "$Array",
"cond": { "$eq": [ "$$this.field1", "a" ] }
}
}
}
}}
])

或使用 $reduce “重新发明轮子” :

db.collection.aggregate([
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
])

或者你试图用 $unwind 做什么,你其实 $group 再次“计算”有多少匹配项:

db.collection.aggregate([
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
])

前两种形式是现代 MongoDB 环境的“最佳”形式。 $unwind 的最终形式和 $group 是一种“遗留”构造,自 MongoDB 2.6 以来,这种类型的操作实际上并不是必需的,尽管使用了一些略有不同的运算符。

在前两个中,我们基本上是在比较 field1每个数组元素的值,同时它仍然是一个数组。两者 $filter $reduce 是现代运算符,旨在与现有阵列一起使用。使用聚合 $eq 对每个进行相同的比较运算符,它根据给定的参数是否“相等”返回一个 bool 值。在这种情况下,每个数组成员的预期值都是 "a" .

$filter 的情况下,数组实际上保持完整,除了不满足 "cond" 中提供的条件的任何元素。从数组中删除。因为我们仍然有一个“数组”作为输出,所以我们可以使用 $size 运算符来测量处理该过滤条件后剩余的数组元素数。

$reduce 另一方面处理数组元素并为每个元素提供一个表达式和一个存储的“累加器”值,我们用 "initialValue" 初始化它.在这种情况下,相同的 $eq 测试在 $cond 内应用运算符(operator)。这是一个“三元”或if/then/else条件运算符允许返回 bool 值的测试表达式返回 then true 时的值或 else false 时的值.

在那个表达式中我们返回 10分别提供返回值和当前“累加器”相加的总体结果 "$$value" $sum 运算符将它们加在一起。

使用的最终形式 $unwind 在阵列上。这实际上是解构数组成员,为每个数组成员创建一个“新文档”,它是原始文档中的相关父字段。这有效地为每个数组成员“复制”了主文档。

一旦你 $unwind 文件的结构改为"更扁平"的形式。这就是为什么您可以执行后续操作的原因 $match 管道阶段删除不匹配的文档。

这将我们带到了 $group 它用于“汇集”与公共(public) key 相关的所有信息。在这种情况下,它是 _id原始文档的字段,当然会复制到 $unwind 生成的每个文档中.当我们回到这个作为单个文档的“公共(public)键”时,我们可以使用 $sum 来“计算”从数组中提取的剩余“文档”。蓄能器。

如果我们想要返回剩余的“数组”,那么您可以 $push 并只用剩余的成员重建数组:

  { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}

但当然不是使用 $size 在另一个管道阶段,我们仍然可以简单地“计数”,就像我们已经对 $sum 所做的那样。

关于mongodb - 聚合计数数组成员匹配条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50641846/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com