【问题标题】:MongoDB aggregate count of items in two arrays across different documents is the same?MongoDB跨不同文档的两个数组中的项目总计数相同吗?
【发布时间】:2015-11-16 09:44:16
【问题描述】:

这是我的 MongoDB 集合架构:

company: String
model: String
cons: [String] // array of tags that were marked as "cons"
pros: [String] // array of tags that were marked as "pros"

这是我的query

[
    { "$project": {
        "company": 1,
        "model": 1,
        "data": {
            "$setUnion": [
                { "$map": {
                    "input": "$pros",
                    "as": "pro",
                    "in": {
                        "type": "$pro",
                        "value": "$$pro"
                    }
                }},
                { "$map": {
                    "input": "$cons",
                    "as": "con",
                    "in": {
                        "type": "$con",
                        "value": "$$con"
                    }
                }}
            ]
        }
    }},
    { "$unwind": "$data" },
    { "$group": {
      "_id": { 
          "company": "$company",
          "model": "$model",
          "theTag": "$data.value"
      },
      "sumPros": { 
        "$sum": { 
          "$cond": [
            { "$eq": [ "$data.type", "$pro" ] },
              1,
              0
          ]
        }
      },
      "sumCons": { 
        "$sum": { 
          "$cond": [
            { "$eq": [ "$data.type", "$con" ] },
              1,
              0
          ]
        }
      }
    }},
    { "$group": {
        "_id": { 
            "company": "$_id.company",
            "model": "$_id.model",
        },
        "tags": {$push: { 
          "tag": "$_id.theTag", 
          "pros": "$sumPros",
          "cons": "$sumCons"
        }

      }}
}]

这是输出:

{
        "_id": {
            "company": "Lenovo",
            "model": "T400"
        },
        "tags": [
            {
                "tag": "Quality",
                "pros": 64, // expected value is 54
                "cons": 64  // expected value is 10
            },
            {
                "tag": "Value",
                "pros": 76, // expected value is 30
                "cons": 76  // expected value is 46
            }
        ]
}
...

注意proscons 的值是相同的。出于某种原因,它们代表proscons 的总和,我不知道为什么。

我做错了什么?

更新:

这里是集合中的一个文档:

{
  "company": "Lenovo",
  "model": "X200",

  "cons": [
      "Quality"
  ],
  "pros": [
      "Value",
      "Styling"
  ]
}

【问题讨论】:

  • 不应该。你能用一个数据样本来扩展这个问题吗?
  • @BlakesSeven 什么数据样本?
  • 嗯,基本上人们可以剪切和粘贴并使用它来确认您的结果。我会很高兴地在这里添加“您的查询”实际上是从这里的早期问题中收集的“我的逻辑”。但是可以这么说,我一直在“蒙着眼睛”工作,因为您的问题都没有提供实际数据可供使用。逻辑应该是合理的,但请展示一些我们都可以尝试使用的基本集合数据。
  • @BlakesSeven 这是评论的集合,这意味着有很多文档具有相同的model 名称

标签: javascript mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

作为您在查询中使用的内容的作者,并且在要求您以数据形式提交一些实际支持问题中的主张的信息之后,我不得不说您所说的是不正确的.

作为记录,这是您在回答时的示例:

{
  "company": "Lenovo",
  "model": "X200",

  "cons": [
      "Quality"
  ],
  "pros": [
      "Value",
      "Styling"
  ]
}

在您的示例中,如果我运行以下查询(并且我确实对先前答案中的任何误导性操作承担责任并将立即修改这些),那么我看到的结果应该是预期的:

db.collection.aggregate([
    { "$project": {
        "company": 1,
        "model": 1,
        "data": {
            "$setUnion": [
                { "$map": {
                    "input": "$cons",
                    "as": "con",
                    "in": {
                        "type": { "$literal": "con" },
                        "value": "$$con"
                    }
                }},
                { "$map": {
                    "input": "$pros",
                    "as": "pro",
                    "in": {
                        "type": { "$literal": "pro" },
                        "value": "$$pro"
                    }
                }}
            ]
        }
    }},
    { "$unwind": "$data" },
    { "$group": {
        "_id": {
            "company": "$company",
            "model": "$model",
            "tag": "$data.value"
        },
        "pros": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$data.type", "pro" ] },
                    1,
                    0
                ]
            }
        },
        "cons": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$data.type", "con" ] },
                    1,
                    0
                ]
            }
        }
    }}
])

从你的样品中产生的

{
    "_id" : {
            "company" : "Lenovo",
            "model" : "X200",
            "tag" : "Quality"
    },
    "pros" : 0,
    "cons" : 1
}
{
    "_id" : {
            "company" : "Lenovo",
            "model" : "X200",
            "tag" : "Value"
    },
    "pros" : 1,
    "cons" : 0
}
{
    "_id" : {
            "company" : "Lenovo",
            "model" : "X200",
            "tag" : "Styling"
    },
    "pros" : 1,
    "cons" : 0
}

这清楚地正确分配了分组键中的“优点”和“缺点”总数,正如预期的那样。

因此,这里“我看到”的是,这些值实际上并不“相同”,但实际上是“不同”的,因为它们与赋予每个字段累加器的不同条件相匹配。


因此更进一步,并基于您的original question

db.collection.aggregate([
    { "$project": {
        "company": 1,
        "model": 1,
        "data": {
            "$setUnion": [
                { "$map": {
                    "input": "$cons",
                    "as": "con",
                    "in": {
                        "type": { "$literal": "con" },
                        "value": "$$con"
                    }
                }},
                { "$map": {
                    "input": "$pros",
                    "as": "pro",
                    "in": {
                        "type": { "$literal": "pro" },
                        "value": "$$pro"
                    }
                }}
            ]
        }
    }},
    { "$unwind": "$data" },
    { "$group": {
        "_id": {
            "company": "$company",
            "model": "$model",
            "tag": "$data.value"
        },
        "pros": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$data.type", "pro" ] },
                    1,
                    0
                ]
            }
        },
        "cons": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$data.type", "con" ] },
                    1,
                    0
                ]
            }
        }
    }},
    { "$group": {
        "_id": {
            "company": "$_id.company",
            "model": "$_id.model"
        },
        "data": { "$push": {
            "tag": "$_id.tag",
            "pros": "$pros",
            "cons": "$cons"
        }}
    }}
])

生产:

{
    "_id" : {
            "company" : "Lenovo",
            "model" : "X200"
    },
    "data" : [
            {
                    "tag" : "Quality",
                    "pros" : 0,
                    "cons" : 1
            },
            {
                    "tag" : "Value",
                    "pros" : 1,
                    "cons" : 0
            },
            {
                    "tag" : "Styling",
                    "pros" : 1,
                    "cons" : 0
            }
    ]
}

这正是您所要求的。

【讨论】:

  • 您的解决方案的问题在于,您有一个所有模型的所有标签的列表,但我需要的是一个模型的列表 并有一个带有标签列表的tags 属性(如tags: [{tag: "SomeTag", cons: 3, pros: 4}]
  • @MikeVayvala 这里“没问题”。您需要做的就是应用您在此主题上询问的first question 中的课程,然后添加第二个$group 以便将$push 结果内容添加到数组中。我需要再重复一遍吗?
  • 如果你查看我的查询版本,你会发现我做了$push,现在我遇到了一个完全不同的问题(在问题中描述)
  • 这个答案完全是题外话。
  • @MikeVayvala 我真的不明白你在说什么。你对帮助你的人的粗鲁也是不可接受的。查看编辑的详细信息。 “离题”的答案?不知道你在想什么。喝杯咖啡休息一下,做一些阅读/学习。
猜你喜欢
  • 2015-11-16
  • 2015-11-16
  • 2017-11-19
  • 2020-06-26
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多