Учитывая перечень документов, таких как:
[
{
_id: 1,
field: {
subfield1: {
subsubfield1: [
"value",
"test"
]
},
subfield2: {
subsufield2: [
"value"
]
}
},
paths: [
"field.subfield1.subsubfield1",
"field.subfield2.subsubfield2"
]
},
{
_id: 2,
field: {
subfield1: {
subsubfield1: [
"value"
]
},
subfield2: {
subsufield2: [
"value",
"test"
]
}
},
paths: [
"field.subfield2.subsubfield2"
]
},
{
_id: 3,
field: {
subfield1: {
subsubfield1: [
"value"
]
},
subfield2: {
subsufield2: [
"value"
]
}
},
paths: [
"field.subfield1.subsubfield1"
]
},
{
_id: 4,
field: {
subfield1: {
subsubfield1: [
"value"
]
},
subfield2: {
subsufield2: [
"value"
]
}
},
paths: [
"field.subfield1.subsubfield1"
"field.subfield2.subsubfield2"
]
}
]
в котором поле paths представляет собой массив с путями к документу. Мне нужно вернуть документы, которые имеют значение test хотя бы в одном из путей, указанных в массиве paths. Например, будут возвращены документы с _id 1 и _id 2, поскольку хотя бы одно из значений paths является путем в документе со значением test. Документы с _id 3 и _id 4 не возвращаются, поскольку ни один элемент paths не является путем в документе, имеющим значение test.

Обновлено: поскольку OP обновил предположение, что поле всегда вложено в 3 уровня. Это фактически упрощает сценарий и, следовательно, конвейер агрегации.
$objectToArray для анализа объекта field как массива кортежа k-v с именем parsed$map для перебора массива parsedk, чтобы добавить field. в качестве префикса$match только если какой-либо элемент массива parsed находится внутри массива paths и имеет значение testdb.collection.aggregate([
{
"$set": {
"parsed": {
"$map": {
"input": {
"$objectToArray": "$field"
},
"as": "kv",
"in": {
k: {
"$concat": [
"field",
".",
"$$kv.k"
]
},
v: "$$kv.v"
}
}
}
}
},
{
"$set": {
"parsed": {
"$reduce": {
"input": "$parsed",
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
{
"$map": {
"input": {
"$objectToArray": "$$this.v"
},
"as": "kv",
"in": {
k: {
"$concat": [
"$$this.k",
".",
"$$kv.k"
]
},
v: "$$kv.v"
}
}
}
]
}
}
}
}
},
{
"$match": {
"$expr": {
"$anyElementTrue": {
"$map": {
"input": "$parsed",
"as": "p",
"in": {
//1. matching
"$and": [
// 1.1 matching path
{
"$in": [
"$$p.k",
"$paths"
]
},
// 1.2 matching value "test"
{
"$in": [
"test",
"$$p.v"
]
}
]
}
}
}
}
}
}
])
@biorubenfs Это на самом деле упрощает сценарий, поскольку с динамическим уровнем вложенности сложнее всего справиться. Пожалуйста, проверьте обновленный ответ.
Спасибо за ваши усилия @ray. Я очень ценю. Я отредактировал вопрос, потому что думаю, что плохо объяснил. Структура поля всегда имеет 3 уровня (т. е. поле.подполе1.подподполе1. Надеюсь, это облегчит ответ. Я знаю, что схема сложна, но изменить ее сейчас невозможно.