MongoDB基于子文档的键/值排序

时间:2018-11-17 00:03:31

标签: mongodb sorting aggregation-framework entity-attribute-value

所以我有一个名为data的动态集合,其中包含此类文档:

[
    {
        _id: 1,
        module_id: 5,
        dynamic_fields: [
            {key: "title", value: "title 1"},
            {key: "rate", value: 3},
            {key: "category", value: 12},
            {key: "body", value: "my content goes here 1"},
        ]
    },
    {
        _id: 2,
        module_id: 5,
        dynamic_fields: [
            {key: "title", value: "title 2"},
            {key: "rate", value: 5},
            {key: "category", value: 12},
            {key: "body", value: "my content goes here 2"},
        ]
    },
    {
        _id: 3,
        module_id: 5,
        dynamic_fields: [
            {key: "title", value: "title 3"},
            {key: "rate", value: 2},
            {key: "category", value: 12},
            {key: "body", value: "my content goes here 3"},
        ]
    }
]

问题:

如何获取带有dynamic_fields[key:category]=12的所有文档,并按其子文档的rate值对其进行排序。

谢谢。

1 个答案:

答案 0 :(得分:0)

让我们尝试一下。

  1. mongodb-runner startuseful tool!
  2. mongo
  3. 获取一些测试数据:

    db.test.insertMany([
     {
         _id: 1,
         module_id: 5,
         dynamic_fields: [
             {key: "title", value: "title 1"},
             {key: "rate", value: 3},
             {key: "category", value: 12},
             {key: "body", value: "my content goes here 1"},
         ]
     },
     {
         _id: 2,
         module_id: 5,
         dynamic_fields: [
             {key: "title", value: "title 2"},
             {key: "rate", value: 5},
             {key: "category", value: 12},
             {key: "body", value: "my content goes here 2"},
         ]
     },
     {
         _id: 3,
         module_id: 5,
         dynamic_fields: [
             {key: "title", value: "title 3"},
             {key: "rate", value: 2},
             {key: "category", value: 12},
             {key: "body", value: "my content goes here 3"},
         ]
     }
    ])
    

现在我们有了测试数据(请注意,我将dynamic_fields制成了一个数组,因此插入不会出错)。

我们需要分阶段进行此操作。如果您想了解发生了什么,可以从$match阶段开始运行,然后添加每个阶段以查看管道如何转换。

db.test.aggregate(
    { $match: { "dynamic_fields.key": "category", "dynamic_fields.value": 12} },
    // add a field that we can sort on.
    { $addFields: {
        "order": {
            $filter: {
              "input": "$dynamic_fields",
              "as": "d",
              "cond": { "$eq": [ "$$d.key", "rate" ] }
            }
        }
    }},
    // order is an array of one, so we unwind it so we have an object that 
    // we can sort on.
    { $unwind: "$order"},
    { $sort: {
        'order.value': 1 }
    }
);