我试图只获取特定嵌入文档的一个字段。
嵌入式文档应根据两个条件进行过滤 然后只返回该嵌入文档的一个字段。
db.usertest.insertMany(
[{
"username" : "userA",
"objects" : [
{
"type" : "fruit",
"origin" : "ABC",
"name" : "banana",
},
{
"type" : "fruit",
"origin" : "XYZ",
"name" : "pineapple",
},
{
"type" : "vegetable",
"origin" : "XYZ",
"name" : "carrot"
}
]
},
{
"username" : "userB",
"objects" : []
}
]
)
我想找到字段"用户名"和#34;名称"的 嵌入式文件。
首先我想到了$ elemMatch,但我被困在了$ project部分 它只返回字段" name"所有嵌入文件的时候 $ elemMatch是真的。
db.usertest.aggregate(
[{$match:{"objects": {"$elemMatch":{
"type": "fruit",
"origin": "XYZ"}}}},
{$project: {
"username":1,
"objects.name":1
}}]
).pretty()
然后我想到了使用$ filter,但它显然只是返回了 整个嵌入式文档而不仅仅是字段" name"。
db.usertest.aggregate(
[{$project: {
"username":1,
"name":{
$filter: {
input: "$objects",
cond: { $and: [
{ $eq: [ "$$this.type", "fruit" ] },
{ $eq: [ "$$this.origin", "XYZ" ] }
]}
}}
}}]
).pretty()
有什么想法吗?
答案 0 :(得分:1)
您可以按以下顺序组合多个聚合运算符:
$filter - > $map(仅获取name
属性) - > $arrayElemAt(采取第一个元素)
db.usertest.aggregate(
[{$project: {
"username":1,
"name": {
$arrayElemAt: [
{
$map: {
input: {
$filter: {
input: "$objects",
cond: { $and: [
{ $eq: [ "$$this.type", "fruit" ] },
{ $eq: [ "$$this.origin", "XYZ" ] }
]}
}},
as: "item",
in: "$$item.name"
}
},0
]
}
}}]
).pretty()
答案 1 :(得分:1)
$project
阶段有no $elemMatch operator
。因此,要使用模拟类似功能,您可以使用索引为0和$filter
的{{1}}创建$arrayElemAt
,以将中间文档保存在变量中并输出名称。
保留$let
阶段,以便只查看至少有一个匹配对象的文档。
像
这样的东西$match