在mongodb聚合管道中,我要$project
与上一个$match
阶段匹配的嵌入式数组(子文档)的索引。
说,我有以下文档。
{_id: '1', tags: ['aaa', 'bbb', 'ccc']},
{_id: '2', tags: ['baa', 'aaa', 'aaa']},
{_id: '3', tags: ['aac', 'cbb', 'aca']},
现在,如果我用{tags: 'aaa'}
查询,我想输出类似于
{_id: '1', tags: [0]},
{_id: '2', tags: [1, 2]}
答案 0 :(得分:1)
db.inventory.aggregate([
{ $match : {tags : 'aaa' }},
{ $unwind : { path: "$tags", includeArrayIndex: "arrayIndex"}},
{ $match : {tags : 'aaa' }},
{ $group : {
_id : '$_id',
tags : { $push : '$arrayIndex'}
}
}
])
输出:
{ "_id" : "2", "tags" : [ NumberLong(1), NumberLong(2) ] }
{ "_id" : "1", "tags" : [ NumberLong(0) ] }
另一种方式:
db.inventory.aggregate([
{ $match : {tags : 'aaa' }},
{ $project : {
tags: {
$filter: {
input: {
$zip: {
inputs: [ "$tags", { $range: [0, { $size: "$tags" }] } ]
}
},
as: "tagWithIndex",
cond: {
$let: {
vars: {
tag : { $arrayElemAt: [ "$$tagWithIndex", 0 ] }
},
in: { $eq: [ "$$tag", 'aaa' ] }
}
}
}
}
}},
{ $unwind : '$tags'},
{ $group : {
_id : '$_id',
tags : {
$push : { $arrayElemAt: [ "$tags", 1]}
}
}
}
])
输出:
{ "_id" : "2", "tags" : [ 1, 2 ] }
{ "_id" : "1", "tags" : [ 0 ] }
希望这会有所帮助。
答案 1 :(得分:1)
您需要$map
在$tags
数组的$size
上,以包含tags
数组中每个元素的索引,然后可以轻松使用{{3 }}聚合以排除确实包含字母aaa
db.collection.aggregate([
{ "$match": { "tags": "aaa" }},
{ "$project": {
"tags": {
"$filter": {
"input": {
"$map": {
"input": { "$range": [0, { "$size": "$tags" }] },
"in": {
"string": { "$arrayElemAt": ["$tags", "$$this"] },
"index": "$$this"
}
}
},
"cond": { "$eq": ["$$this.string", "aaa"] }
}
}
}},
{ "$project": { "tags": "$tags.index" }}
])
[
{
"_id": "1",
"tags": [0]
},
{
"_id": "2",
"tags": [1, 2]
}
]
答案 2 :(得分:0)
如果要搜索数组,则应使用$ in。
db.inventory.find( { tags: { $in: [ 'aaa' ] } } )
您也可以在比赛中写下相同的内容。拼写是一样的。
将提供详细帮助。这就是您要寻找的。 p>
来源:https://docs.mongodb.com/manual/reference/operator/query/in/
db.inventory.find( { "tags": { $in: 'aaa' } },
{ "tags.$": 1 } )
这可能就是您想要的。