MongoDB - 将结果作为标量值数组检索

时间:2017-09-26 10:34:02

标签: python mongodb mongodb-query

首先,如果我的英语不是很好,我很抱歉,我希望我写的内容是可以理解的。

我有一个包含此架构的文档:

{
    "fields":[
         {"field": field1, "value": 1},
         {"field": field2, "value": 2},
         {"field": field3, "value": 3}
     ],
     "time": datetimeObj
},
{
    "fields":[
        {"field": field1, "value": 4},
        {"field": field4, "value": 5}
    ],
    "time": datetimeObj
}

我尝试做的是生成一个返回一个特定字段值列表的查询。

例如,如果我想要字段的值" field1"我希望有类似的东西:

[1, 4]

对于字段" field2":

[2, 0] // 0 because it doesn't exist in the second document

现在我尝试使用聚合运算符来获取此结果:

db.collection.aggregate([
{
  $project: {
     value: {
        $filter: {
           input: "$fields",
           as: "fields",
           cond: { $eq: [ "$$fields.filed", "filed1" ] }
        }
     },
     _id : 0
  }
}

但我得到的是比我想要的更加冗长:

{ 
"value" : [
    {
        "value" : NumberInt(1), 
        "filed" : "field1"
    }
]
}
{ 
 "value" : [
    {
        "value" : NumberInt(4), 
        "word" : "field1"
    }
  ]
}

有没有办法让结果像一组值一样?此外,是否可以按时间字段对这些值进行排序?

我正在使用python库,因此拥有解决方案的python示例非常有用。谢谢

2 个答案:

答案 0 :(得分:0)

根据上述描述作为解决方案,请尝试执行以下聚合查询到MongoDB shell。

db.collection.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $unwind: {
                path: "$fields"
            }
        },

        // Stage 2
        {
            $group: {
                _id: {
                    fields: '$fields.field',
                    time: '$time'
                },
                value: {
                    $addToSet: '$fields.value'
                },

            }
        },

        // Stage 3
        {
            $match: {
                '_id.fields': 'field1'
            }
        },

        // Stage 4
        {
            $project: {
                "fields": '$_id.fields',
                value: '$value',
                time: '$_id.time',
                _id: 0
            }
        },

        // Stage 5
        {
            $sort: {
                time: 1
            }
        },

    ]



);

答案 1 :(得分:0)

您可以尝试以下聚合查询。

$addFields $cond检查fields数组是否包含($infield1个文档,如果找到则保留fields数组或者创建一个fields数组包含{"field": "field1", "value": 0}个文档,后跟$unwind$match仅保留field1个文档。

{p} $sort time以及$group$slice来收集值。

 db.collection.aggregate([
  {
    "$addFields": {
      "fields": {
        "$cond": [
          {
            "$in": [
              "field1",
              "$fields.field"
            ]
          },
          "$fields",
          [
            {
              "field": "field1",
              "value": 0
            }
          ]
        ]
      }
    }
  },
  {
    "$unwind": "$fields"
  },
  {
    "$match": {
      "fields.field": "field1"
    }
  },
  {
    "$sort": {
      "time": 1
    }
  },
  {
    "$group": {
      "_id": "null",
      "values": {
        "$push": "$fields.value"
      }
    }
  },
  {
    "$project": {
      "values": {
        "$slice": [
          "$values",
          12
        ]
      }
    }
  }
])