Mongodb 在嵌套数组中的特定元素上投影
我有一份这样的文件Mongodb 在嵌套数组中的特定元素上投影,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一份这样的文件 { "_id" : ObjectId("59b0ea9b3a91af574a3e0464"), "machineID" : "b83c", "sensorState" : [ { "data" : "377", "sensor" : "solar", "time" : ISODate("2017-09-20T19:42:58.766Z") },
{
"_id" : ObjectId("59b0ea9b3a91af574a3e0464"),
"machineID" : "b83c",
"sensorState" : [
{
"data" : "377",
"sensor" : "solar",
"time" : ISODate("2017-09-20T19:42:58.766Z")
},
{
"data" : "35",
"sensor" : "photosynthetic",
"time" : ISODate("2017-09-20T19:42:58.782Z")
},
{
"data" : "370",
"sensor" : "solar",
"time" : ISODate("2017-09-20T19:43:29.089Z")
},
{
"data" : "400",
"sensor" : "solar",
"time" : ISODate("2017-09-20T19:44:29.089Z")
},
{
"data" : "35",
"sensor" : "photosynthetic",
"time" : ISODate("2017-09-20T19:43:29.110Z")
}
]
}
我只想检索sensorState
数组中与sensor=solar
匹配的子文档。所以,我试着这样做:
db.getCollection('sensorDB').find({ },
{ "sensorState" : { $elemMatch: {data : "35" } } })
但它只显示了一个结果:
{
"_id" : ObjectId("59b0ea9b3a91af574a3e0464"),
"sensorState" : [
{
"data" : "35",
"sensor" : "photosynthetic",
"time" : ISODate("2017-09-20T19:42:58.782Z")
}
]
}
但是,我想在
sensorState
数组中查找与sensor=solar
匹配的所有子文档。看起来,$elemMatch
只能选择一个结果。您正在尝试使用elemMatch进行项目,但根据
$elemMatch
运算符将查询结果中字段的内容限制为仅包含与$elemMatch
条件匹配的第一个元素
因此,您看到的行为是elemMatch-in-a-projection的预期行为
您可以在聚合管道中使用$project
和$filter
来获得最终结果
给定OP中包含的示例文档,请使用以下命令
db.getCollection('elemMatch').aggregate([
// projects on the sensorState sub documents and filters the output to only return sub
// documents having data=35
{$project: {
sensorState: {
$filter: {
input: "$sensorState",
as: "sensorState",
cond: { $eq: [ "$$sensorState.data", '35' ] }
}
}
}
}
])
。。。将返回:
{
"_id" : ObjectId("59b0ea9b3a91af574a3e0464"),
"sensorState" : [
{
"data" : "35",
"sensor" : "photosynthetic",
"time" : ISODate("2017-09-20T19:42:58.782Z")
},
{
"data" : "35",
"sensor" : "photosynthetic",
"time" : ISODate("2017-09-20T19:43:29.110Z")
}
]
}
您的问题显示试图在data=35
上进行匹配,但也说明:
我要查找所有sensorState.sensor=solar
这是上面的命令,条件是:
db.getCollection('elemMatch').aggregate([
// projects on the sensorState sub documents and filters the output to only return sub
// documents having sensor=solar
{$project: {
sensorState: {
$filter: {
input: "$sensorState",
as: "sensorState",
cond: { $eq: [ "$$sensorState.sensor", 'solar' ] }
}
}
}
}
])
返回:
{
"_id" : ObjectId("59b0ea9b3a91af574a3e0464"),
"sensorState" : [
{
"data" : "377",
"sensor" : "solar",
"time" : ISODate("2017-09-20T19:42:58.766Z")
},
{
"data" : "370",
"sensor" : "solar",
"time" : ISODate("2017-09-20T19:43:29.089Z")
},
{
"data" : "400",
"sensor" : "solar",
"time" : ISODate("2017-09-20T19:44:29.089Z")
}
]
}
我自己找到了答案。使用聚合 答案是这样的
db.getCollection('sensorDB').aggregate(
{$match: {machineID:"b83c"}},
{$unwind:"$sensorState"},
{$match: {"sensorState.sensor":"solar"}}
)
getCollection('sensorDB').find({'sensorState.data':“35”,'sensorState.sensor':“solar”})。试试这个