我对 Mongoose 完全陌生。
我有这样的Schema:
const houseSchema = new mongoose.Schema({
_id: String,
housename: {type: String,unique: true},
adress: String,
people: [ {
name: String,
age: Number
} ],
});
字符串
并记录:
let house = new House({
_id: 20,
housename: "white",
adress: "St1",
people:[
{name: "Jon", age: 23},
{name: "Ann", age:50},
{name: "Pat", age:20},
{name: "Helen", age:15}]
});
型
我想通过id找到这个文档,并通过年龄过滤people数组,然后返回没有过滤对象的完整文档。因此预期输出将是:(对于年龄>21):
{
_id: 20,
housename: "white",
adress: "St1",
people:[
{_id:"65976faeaa644d02c4090826", name: "Jon", age: 23},
{_id:"65976faeaa644d02c4090827", name: "Ann", age:50}
]
}
型
经过几个小时的尝试,我对这个问题的解决方案是:
app.get("/api/test", (req, res) => {
var searchID = "20";
var minAge = 21;
House.aggregate([{$match: {_id: searchID}}])
.unwind("people").match({'people.age': {$gt: minAge}})
.group({
_id: "$_id",
people: {$push: "$people"}
})
.exec((err,data)=>{
res.json(data);
});
});
型
所以首先我匹配id,然后倒带people数组-这样我就可以过滤掉它,然后我尝试重新加入到第一个表单。**然而,分组后我丢失了 housename 和 adress 字段。**这里是输出:
{"_id":"20",
"people":[
{"_id":"65976faeaa644d02c4090826","name":"Jon","age":23},{"_id":"65976faeaa644d02c4090827","name":"Ann","age":50}]}
型
我不知道如何在输出中保留 housename 和 adress 字段。我试过添加.projection({housename:1,adress:1...});,但它什么也没做,我认为这些键在group()之后的管道中不存在。我也一直在考虑将这些值保存到match()之后的vars中,然后在末尾添加它们,但我不知道如何在链的中间访问它们。
1条答案
按热度按时间wmtdaxz31#
你可以使用一个简单的
$filter
来过滤符合过滤条件的people
对象,如下所示:字符串
请参阅HERE以获取工作示例。
$addFields
的使用在这里很重要,因为:向文档添加新字段。
$addFields
输出包含输入文档中所有现有字段和新添加字段的文档。$addFields
stage等效于$project
stage,它显式指定输入文档中所有现有字段并添加新字段。我想这就是你在使用
$project
时遇到麻烦的地方。我所做的就是使用$addFields
用新的过滤版本覆盖现有的people
属性。