Mongoose / Mongo noob:
我的数据
这是我的简化数据,每个用户都有自己的文档
{ "__v" : 1,
"_id" : ObjectId( "53440e94c02b3cae81eb0065" ),
"email" : "test@test.com",
"firstName" : "testFirstName",
"inventories" : [
{ "_id" : "active",
"tags" : [
"inventory",
"active",
"vehicles" ],
"title" : "activeInventory",
"vehicles" : [
{ "_id" : ObjectId( "53440e94c02b3cae81eb0069" ),
"tags" : [
"vehicle" ],
"details" : [
{ "_id" : ObjectId( "53440e94c02b3cae81eb0066" ),
"year" : 2007,
"transmission" : "Manual",
"price" : 1000,
"model" : "Firecar",
"mileageReading" : 50000,
"make" : "Bentley",
"interiorColor" : "blue",
"history" : "CarProof",
"exteriorColor" : "blue",
"driveTrain" : "SWD",
"description" : "test vehicle",
"cylinders" : 4,
"mileageType" : "kms" } ] } ] },
{ "title" : "soldInventory",
"_id" : "sold",
"vehicles" : [],
"tags" : [
"inventory",
"sold",
"vehicles" ] },
{ "title" : "deletedInventory",
"_id" : "deleted",
"vehicles" : [],
"tags" : [
"inventory",
"sold",
"vehicles" ] } ] }
如您所见,每个用户都有一个inventories
属性,该属性是一个包含3个库存的数组(activeInventory,soldInventory和deletedInventory)
我的查询
如果用户的电子邮件是车辆ID,我希望我的查询通过查找用户的activeInventory
并仅返回与ID匹配的车辆。以下是我到目前为止的情况:
user = api.mongodb.userModel;
ObjectId = require('mongoose').Types.ObjectId;
return user
.findOne({email : params.username})
.select('inventories')
.find({'title': 'activeInventory'})
//also tried
//.where('title')
//.equals('activeInventory')
.exec(function(err, result){
console.log(err);
console.log(result);
});
有了这个,结果就像一个空数组。我也尝试了.find('inventories.title': 'activeInventory')
奇怪地返回整个库存数组。如果可能的话,我想保留链接查询格式,因为我发现它更具可读性。
我理想的查询
return user
.findOne({email : params.username})
.select('inventories')
.where('title')
.equals('activeInventory')
.select('vehicles')
.id(vehicleID)
.exec(cb)
显然它不起作用,但它可以让你知道我想要做什么。
答案 0 :(得分:6)
使用$
位置运算符,您可以获得结果。但是,如果vehicles
数组中有多个元素,则结果中将返回所有元素,因为您只能在投影中使用一个位置运算符,而您正在使用2个数组(一个在另一个内部)。 / p>
我建议你看看aggregation framework
,因为你会获得更大的灵活性。这是一个在shell中运行的问题的示例查询。我不熟悉猫鼬,但我想这仍然可以帮助你,你可以翻译它:
db.collection.aggregate([
// Get only the documents where "email" equals "test@test.com" -- REPLACE with params.username
{"$match" : {email : "test@test.com"}},
// Unwind the "inventories" array
{"$unwind" : "$inventories"},
// Get only elements where "inventories.title" equals "activeInventory"
{"$match" : {"inventories.title":"activeInventory"}},
// Unwind the "vehicles" array
{"$unwind" : "$inventories.vehicles"},
// Filter by vehicle ID -- REPLACE with vehicleID
{"$match" : {"inventories.vehicles._id":ObjectId("53440e94c02b3cae81eb0069")}},
// Tidy up the output
{"$project" : {_id:0, vehicle:"$inventories.vehicles"}}
])
这是你得到的输出:
{
"result" : [
{
"vehicle" : {
"_id" : ObjectId("53440e94c02b3cae81eb0069"),
"tags" : [
"vehicle"
],
"details" : [
{
"_id" : ObjectId("53440e94c02b3cae81eb0066"),
"year" : 2007,
"transmission" : "Manual",
"price" : 1000,
"model" : "Firecar",
"mileageReading" : 50000,
"make" : "Bentley",
"interiorColor" : "blue",
"history" : "CarProof",
"exteriorColor" : "blue",
"driveTrain" : "SWD",
"description" : "test vehicle",
"cylinders" : 4,
"mileageType" : "kms"
}
]
}
}
],
"ok" : 1
}
答案 1 :(得分:3)
获取链接查询格式...我不知道如何解析它但是,你要搜索的是投影,你应该看看http://docs.mongodb.org/manual/reference/operator/projection/
它可能看起来像这样:
user.findOne({email: params.username}, {'inventories.title': {$elemMatch: "activeInventory", 'invertories.vehicle.id': $elemMatch: params.vehicleId}, function(err, result) {
console.log(err);
console.log(result);
})