【发布时间】:2018-01-06 16:03:58
【问题描述】:
我想知道如何从 Mongoose 查询中为匹配的对象数组设置投影。
例如,如果我有一个看起来像这样的 Mongoose 模型:
var User = new Schema({
name: String,
children: [Child]
});
var Child = new Schema({
name: String,
height: Number,
age: Number,
secret: Number
});
换句话说,一个可能由此模型产生的示例 JSON 对象:
User: {
name: 'abc',
children: [
{
name: 'def',
height: 123,
age: 7,
secret: 2
},
{
name: 'ghi',
height: 456,
age: 9,
secret: 3
}
]
}
如您所见,该模型包含一个属性children,它是Child 对象的数组。
如果我只匹配 User 包含 children 中具有属性 name: 'def' 的项目:
Users.find({
children.name: 'def'
})
然后我可以设置投影以选择属性(例如name)以及使用位置运算符($)从匹配对象中选择属性:
.select({
name: 1,
children.$: 1
}
现在的问题是,使用此投影,children.$ 将始终返回整个 Child 对象,包括我可能不想查询的属性,例如 secret。
{
name: 'abc',
children: [
{
name: 'def',
height: 123,
age: 7,
secret: 2
}
]
}
理想情况下,我还希望能够从通过$ 获得的child 对象中选择某些属性,类似于从父对象User 中选择name,但我找不到方法这个。
选择单个属性的一种方法是使用 children.$.age 格式,但这只能用于选择 1 个属性,因为多次这样做会导致错误,因为您不能多次使用定位 $ 运算符.
.select({
name: 1,
// and now select the height and age
// but only of the child that matches name = 'def'
// WITHOUT returning the entire object (exclude name and secret)
children.$.age,
children.$.height // error
})
是否可以在 Mongoose 中为位置运算符获得的对象选择投影?
【问题讨论】:
-
.find({ 'foo._id': 'def' }).select({ 'bar': 1, 'foo.$.tmp': 1 })。您可能必须滚动链接的答案(有很多),但肯定存在。还指出“单一”属性匹配不需要$elemMatch。 -
@NeilLunn 如果我需要匹配
foo中的多个字段怎么办?现在它返回一个错误,因为我不能有多个位置 $。 -
那么也许您应该真正完整地阅读现有答案,因为也有解决方案。
-
我已完整阅读现有答案数次,但对它们不满意。我已经编辑了我的问题,以更好地反映我的要求。为了澄清起见,我正在寻找一种从对象数组中选择特定字段的方法,类似于我从标准查询中选择字段的方式。对于该线程上给出的所有答案,它们总是返回完整的子对象。
-
你当时没有正确地把它们变红。 Go and read them all again。有几个答案提到了
$filter。
标签: javascript node.js mongodb mongoose