获取数组中具有标签的文档



我在运行MongoDB 4.2.2 Enterprise的Atlas上有以下集合:

{
"items": [
{
"pID": 1111,
"name": "Test Item #1111",
"amount": 11,
"labels": [
"test",
"testcat1"
]
},
{
"pID": 2222,
"name": "Test Item #2222",
"amount": 22,
"labels": [
"test",
"testcat2"
]
},
{
"pID": 3333,
"name": "Test Item #3333",
"amount": 33,
"labels": [
"test",
"testcat3"
]
}
]
}

我的目标是获取一组标签匹配的所有产品。例如,这个想法是我可以搜索["test"]并获取所有 3 个项目,但["test", "testcat1"]应该只返回第一个。

在互联网上搜索,我看到人们建议使用db.inventories.find( { "_id" : 72986, "items.labels" : { $all : ["test", "testcat2"] } } ),但我得到了整个数组,而不仅仅是匹配的项目:

[
{
"pID": 1111,
"name": "Test Item #1111",
"amount": 11,
"labels": [
"test",
"testcat1"
]
},
{
"pID": 2222,
"name": "Test Item #2222",
"amount": 22,
"labels": [
"test",
"testcat2"
]
},
{
"pID": 3333,
"name": "Test Item #3333",
"amount": 33,
"labels": [
"tets",
"testcat3"
]
}
]

当我尝试投影{"items.$" : 1}时,我得到了正确的项目,但只有一个。我需要类似的行为来获取多个项目。

提前感谢!

使用 $elemMatch 或 $ 的问题是它们只会返回第一个匹配的文档 - 如果items.labels有多个匹配的项目对象要传入输入,则会有问题,您可以尝试以下查询:

db.collection.aggregate([{
$addFields: {
'items': {
$filter: {
input: "$items",
as: "item",
cond: { $setIsSubset: [['test',"testcat1"], "$$item.labels"] }
}
}
}
}])

测试:MongoDB-Playground

编号 :$setIsSubset

如果在数组中传递['test',"testcat1"]不是item.labels的子集,那么对于这些文档,响应将是

{
"_id" : ObjectId("5e3332078bbf43c5c046e5e2"),
"items" : []
}

因此,您可能需要在$addFields后有一个$match阶段来删除这些文档。以另一种方式,您可以将$match作为第一阶段,以将文档数量限制为$addFields阶段:

{
$match: {
"items.labels": {
$all: // or can be $in
[
[ "test", "testcat1" ]
]
}
}
}

然后上述阶段将删除字段items.labels没有["test","testcat1"]的文档。

最新更新