给出如下文档列表:
[
{
_id: 1,
field1: "test",
field2: "value2",
fields: [
"field1",
"field2"
]
},
{
_id: 2,
field1: "value1",
field2: "test",
fields: [
"field1",
"field2"
]
},
{
_id: 3,
field1: "test",
field2: "value2",
fields: [
"field2"
]
},
{
_id: 4,
field1: "value1",
field2: "value2",
fields: [
"field1"
]
},
{
_id: 5,
field1: "test",
field2: "test",
fields: []
}
]
我想检索数组中具有任何指定字段且值为“test”的所有文档。例如,在带有
_id: 1
的文档中,field2
是 fields
数组的值,并且 field2
将 test
作为值。相反,带有 _id: 5
的文档具有键 field1
和 field2
以及测试值,但这些字段都不存在于字段数组中。因此,根据之前的文档列表,仅应返回带有 _id: 1
和 _id: 2
的文档。
可能的方法作为步骤
field1
,field2
..创建一个临时键值对数组字段,以便可以过滤/搜索在比赛阶段使用
$anyElementTrue
的方法 - 演示
db.collection.aggregate([
{
$addFields: {
keyValuePairArray: {
$filter: {
input: { $objectToArray: "$$ROOT" },
cond: { $not: { $in: [ "$$this.k", ["_id", "fields"] ] } }
}
}
}
},
{
$match: {
$expr: {
$anyElementTrue: {
$map: {
input: "$keyValuePairArray",
in: {
$and: [
{ $in: [ "$$this.k", "$fields" ] },
{ $eq: [ "$$this.v", "test" ] }
]
}
}
}
}
}
},
{ $unset: "keyValuePairArray" }
])
在比赛阶段使用
$filter
检查其大小的另一种方法 - demo
db.collection.aggregate([
{
$addFields: {
keyValuePairArray: {
$filter: {
input: { $objectToArray: "$$ROOT" },
cond: { $not: { $in: [ "$$this.k", ["_id", "fields"] ] } }
}
}
}
},
{
$match: {
$expr: {
$gt: [
{
$size: {
$filter: {
input: "$keyValuePairArray",
cond: {
$and: [
{ $in: [ "$$this.k", "$fields" ] },
{ $eq: [ "$$this.v", "test" ] }
]
}
}
}
},
0
]
}
}
},
{ $unset: "keyValuePairArray" }
])