需要一些基于子文档属性值的Mongo查询的帮助,但也要求抑制该子文档属性出现在结果中。
以下是我的用户对象:
{
"username" : "abc",
"emails" : [
{
"address" : "abc1@email.com",
"default" : true
},
{
"address" : "abc2@email.com",
"default" : false
}
]
},
{
"username" : "xyz",
"emails" : [
{
"address" : "xyz1@email.com",
"default" : false
},
{
"address" : "xyz2@email.com",
"default" : true
}
]
}
我的目标是获得以下输出(使用“emails.default”:true但结果中没有“emails.default”属性):
{
"username" : "abc",
"emails" : [
{
"address" : "abc1@email.com",
}
]
},
{
"username" : "xyz",
"emails" : [
{
"address" : "xyz2@email.com",
}
]
}
使用$ position运算符:
collection.find({"emails.default":true}, {"username":1,"emails.$":1})
我会显示正确的电子邮件子文档,但我仍然会收到“emails.default”属性:
{
"username" : "abc",
"emails" : [
{
"address" : "abc1@email.com",
"default" : true
}
]
},
{
"username" : "xyz",
"emails" : [
{
"address" : "xyz2@email.com",
"default" : true
}
]
}
由于某种原因,当我使用这个陈述时:
collection.find({"emails.default":true}, {"username":1,"emails.address":1})
我得到以下结果(好像忽略了语句的查询部分)
{
"username" : "abc",
"emails" : [
{
"address" : "abc1@email.com",
},
{
"address" : "abc2@email.com",
}
]
},
{
"username" : "xyz",
"emails" : [
{
"address" : "xyz1@email.com",
},
{
"address" : "xyz2@email.com",
}
]
}
非常感谢,提前感谢。
答案 0 :(得分:3)
使用位置运算符(如MongoDB 2.6),您无法有选择地排除您匹配的数组元素的字段。
但是,您可以使用MongoDB 2.2+中的聚合框架来实现您期望的结果:
db.user.aggregate(
// Match on relevant documents to optimize query
{ $match: {
username: "abc"
}},
// Convert the "emails" address into a stream of documents
{ $unwind: "$emails" },
// Only include the emails with default:true
{ $match: {
"emails.default" : true
}},
// Project the desired fields
{ $project: {
_id : 0,
username: 1,
"emails.address": 1
}}
)
示例结果:
{
"username" : "abc",
"emails" : {
"address" : "abc1@email.com"
}
}
答案 1 :(得分:1)
我不认为这是受支持的功能。您要求在数组文档中投影选定的字段。见ticket
但我认为您的文档结构将存储大量冗余数据。将只有一个默认电子邮件地址。将此作为父文档的一部分。更新/预测将更加简单。您的阵列emails
现在实际上只存储 电子邮件。