检索动态子文档密钥

时间:2018-07-09 15:23:08

标签: mongodb mongodb-query aggregation-framework

我有这个mongo文件

{
    "name": "aaa",
    "Time": "Now",
    "_id": "656i9gfk543klffx",
    "lastReadings": {
        "7-Temperature": {
            "_t": "NumberReading",
            "timestamp": "2017-02-13T12:51:50.000+0000",
            "unit": "C",
            "typeCode": 7,
            "name": "Temperature",
            "numberValue": 11.271406207825713
        },
        "30-DISCONNECT": {
            "_t": "NumberReading",
            "internalTimestamp": "2017-06-02T19:16:33.050+0000",
            "timestamp": "2017-06-02T19:16:27.147+0000",
            "unit": "",
            "typeCode": 30,
            "name": "DISCONNECT",
            "numberValue": 1
        }
    }
},
{
    "name": "aaa",
    "Time": "Now",
    "_id": "gtrg565opgf0",
    "lastReadings": {
        "7-Temperature": {
            "_t": "NumberReading",
            "timestamp": "2017-02-13T12:51:50.000+0000",
            "unit": "C",
            "typeCode": 7,
            "name": "Temperature",
            "numberValue": 46
        },
        "25-Water": {
            "_t": "NumberReading",
            "internalTimestamp": "2017-06-02T19:16:33.050+0000",
            "timestamp": "2017-06-02T19:16:27.147+0000",
            "unit": "",
            "typeCode": 25,
            "name": "Water",
            "numberValue": 1
        }
    }
}

我正在尝试从“ lastReadings”对象中获得不同的字段键,其中“名称”字段等于“ aaa”。 所以我期望的结果是:

["7-Temperature", "30-DISCONNECT","25-Water"]

“ lastReadings”中的子对象键是动态的,我不知道它们的名称以及“ lastReadings”中将有多少文件。

我可以通过哪种聚合查询来获得此结果?

我已经知道了这个查询

{$match: {"name":"aaa"}},
{ $group: { _id: "name", mergedEvents: { $mergeObjects: "$lastReadings" } } }

但是当我有很多文档时,它运行速度似乎很慢(“ lastReadings”上的索引会提高性能吗?)并且它返回不需要的整个对象。

谢谢。

1 个答案:

答案 0 :(得分:0)

好吧,我们可以通过以下管道来做到这一点:

[
   {
      "$group":{
         "_id":null,
         "lastReadings":{
            "$push":{
               "$map":{
                  "input":{
                     "$objectToArray":"$lastReadings"
                  },
                  "in":"$$this.k"
               }
            }
         }
      }
   },
   {
      "$project":{
         "mergeEvent":{
            "$reduce":{
               "input":"$lastReadings",
               "initialValue":[

               ],
               "in":{
                  "$setUnion":{
                     "$concatArrays":[
                        "$$this",
                        "$$value"
                     ]
                  }
               }
            }
         }
      }
   }
]

但是我建议您检查架构设计并删除动态字段的名称。

“ lastReadings”字段如下所示:

{
   "lastReadings":[
      {
         "parameter":"7-Temperature",
         "value":{
            "_t":"NumberReading",
            "timestamp":"2017-02-13T12:51:50.000+0000",
            "unit":"C",
            "typeCode":7,
            "name":"Temperature",
            "numberValue":11.271406207825713
         }
      },
      {
         "parameter":"30-DISCONNECT",
         "value":{
            "_t":"NumberReading",
            "internalTimestamp":"2017-06-02T19:16:33.050+0000",
            "timestamp":"2017-06-02T19:16:27.147+0000",
            "unit":"",
            "typeCode":30,
            "name":"DISCONNECT",
            "numberValue":1
         }
      }
   ]
}

使用这种模式,您可以使用.disctinct方法和点符号

来检索不同的值。
db.collection.distinct("lastReadings.parameter")