我刚开始使用基于文档的数据存储大约3-4个小时,我有一个基本问题,我想了解。
{ "_id": "5527e5ae06e55c02049bd114", "owner": "John Doe", "customers" : ["5527e3c806e55c01dad3a132", "5527e3c806e55c01dad3a133", "5527e3c806e55c01dad3a134"], "location" : [ { "address": "Wall St", "location_id": "123123213", "vendor" : [ { "name" : "hello 123", "price" : "3", "serial" : "000000009730978e" }, { "name" : "hello abc", "price" : "3.5", "serial" : "0000000097308888" } ] }, { "address" : "PCH 1", "location_id": "987987", "vendor" : [ { "name" : "hello 456342", "price" : "4", "serial" : "000000009733452435" }, { "name" : "hello sdfsdg", "price" : "4.5", "serial" : "0000000095243532453" } ] } ] }
那么如何找到location.serial.price?
db.test.find_one( {"location.location_id" : "123123213" , "location.vendor.serial" : "000000009730978e" } )
将返回整个对象,但我只对这些条件匹配的location.serial.price感兴趣。
非常感谢, 本
答案 0 :(得分:1)
通常你会使用positional-operator($)来引用数组条目。但不幸的是,这个运算符有一个严重的限制:它不适用于嵌套数组。所以在这种情况下它没有帮助你。
你可以做的是使用一个聚合管道,unwind是两个数组,然后match是串口。
db.test.aggregate([
// create a stream of location-documents
{ $unwind: "$location" },
// filter the stream by location-id
{ $match: { "location.id" : "123123213" },
// expand the remaining stream further to individual vendor-documents
{ $unwind: "$vendor" },
// filter the stream by serial
{ $match: { "location.vendor.serial": "000000009730978e" } }
]);
请记住,聚合可能会变得很慢。它还具有每个聚合步骤16MB的限制。您可以使用allowDiskUse:true
选项来避免此限制,但这会使速度更慢。因此,当您需要考虑大量数据和性能时,您可能需要重新考虑数据库架构。
答案 1 :(得分:0)
Mongodb aggregation在这里使用,下面的查询将满足您的标准
db.collectionName.aggregate({
"$unwind": "$location"
},
{
"$match": {
"location.location_id": "123123213"
}
},
{
"$unwind": "$location.vendor"
},
{
"$match": {
"location.vendor.serial": "000000009730978e"
}
},
{
"$project": {
"serial": "$location.vendor.serial",
"price": "$location.vendor.price",
"_id": 0
}
}).pretty()