我有这个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”上的索引会提高性能吗?)并且它返回不需要的整个对象。
谢谢。
答案 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")