Mongodb计算集合中存在值的频率

时间:2014-09-03 15:55:50

标签: mongodb mongodb-query aggregation-framework

我尝试编写一个查询,该查询返回值keyword4在我的集合中出现的字段label

的频率
{
    "_id" : ObjectId("54071d4312bf9ee0d67f7cf8"),
    "id" : "2",
    "list" : [ 
        {
            "id" : 60,
            "label" : "keyword3",
            "pos" : 1
        }, 
        {
            "id" : 89,
            "label" : "keyword4",
            "pos" : 2
        }, 
        {
            "id" : 49,
            "label" : "keyword4",
            "pos" : 3
        }
        ]
},
{
    "_id" : ObjectId("5407sfkjsvnsvree9ee0d67f7cf8"),
    "id" : "3",
    "list" : [ 
        {
            "id" : 60,
            "label" : "keyword3",
            "pos" : 1
        }, 
        {
            "id" : 89,
            "label" : "keyword4",
            "pos" : 2
        }, 
        {
            "id" : 49,
            "label" : "keyword4",
            "pos" : 3
        }
        ]
},
...

感谢。

1 个答案:

答案 0 :(得分:2)

您在这里谈论的是“汇总结果”,因此您基本上使用aggregation framework

这些步骤基本上是匹配包含所需值的文档,将数组内容仅过滤到那些匹配项,然后计算该字段值的出现次数。这里的主要运算符是$match,它接受​​.find()确实的查询参数,$unwind允许您使用数组的元素,$group执行实际的“聚合“,或者确实是你的元素的”计数“:

db.collection.aggregate([
    // Match the documents to reduce what you are processing
    { "$match": { "list.label": "keyword4" } },

    // Unwind the array to de-normalize or "un-join"
    { "$unwind": "$list" },

    // Match again to "filter" the array content
    { "$match": { "list.label": "keyword4" } },

    // Group your final results
    { "$group": {
        "_id": "$list.label",
        "count": { "$sum": 1 }
    }}
])

这里的$sum运算符将“求和”它作为参数提供的值。在这种情况下,您可以提供1的基本值,以表示每个匹配事件的递增计数。

此外,这里存在“两个”$match阶段的原因是因为MongoDB的工作方式以及它们分开的事情。第一阶段的目的是匹配满足条件的“文件”。这基本上与.find()的结果相同,因为您匹配文档而不是数组的子文档。该陈述仅说明“包含”符合条件的元素。

第二阶段在$unwind之后“处理”处理,现在集合中的其余文档显示为对数组中存在的每个元素进行“复制”,因此该数组元素为no - 一个数组,但是数组内容中的单个字段或“子文档”。

现在作为单独的文档,第二个$match将“过滤”任何不符合条件的元素。所以现在只有“list.label”值匹配指定的值。您不希望省略第一个$match,因为这意味着在集合中的每个文档上处理$unwind,无论数组元素是否包含匹配项。这意味着你没有通过处理不可能计入结果的事情来做“不必要”的工作。

为了更好地理解和介绍使用聚合框架,文档中的SQL to aggregation mapping page值得关注,至少对于一些常见示例,如果您习惯于SQL表单,则更直接。

通常熟悉一般aggregation operators并了解其功能也是一个好主意。这是一个有用的工具,基本上是一般查询的对应物。非常值得学习,并且使用得很好。