Один из способов обойти это - запустить агрегатный конвейер, который получает данные о ключах на уровне root документа, обозначенного системной переменной $$ROOT
, через их значения и определите, есть ли у них более одного ключа.
Для первого шага введите $addFields
, добавьте дополнительное поле, содержащее вышеприведенные вычисления, и используйте $objectToArray
* 1011. * для преобразования пар ключ / значение в массив [ { k: 'key name': v: 'value' }, ... ]
db.collection.aggregate([
{ '$addFields': {
'fields': { '$objectToArray': '$$ROOT' }
} }
])
При получении этого массива следующим шагом будет фильтрация списка
db.collection.aggregate([
# convert dynamic fields to key/value arrays
{ '$addFields': {
'fields': { '$objectToArray': '$$ROOT' }
} },
# filter where B > 10
{ '$addFields': {
'fields': {
'$filter': {
'input': '$fields',
'cond': {
'$and': [
{ '$ne': [ { '$type' : "$$this.v.B" }, 'missing'] },
{ '$gt': [ "$$this.v.B", 10 ] }
]
}
}
}
} }
])
Конвейеры для затем следуют требуемые запросы:
1. t
s (t_1
, t_2
et c.) для данного _id
, который имеет B
больше 10
db.collection.aggregate([
{ '$addFields': {
'fields': {
'$filter': {
'input': { '$objectToArray': '$$ROOT' },
'cond': {
'$and': [
{ '$ne': [ { '$type' : "$$this.v.B" }, 'missing'] },
{ '$gt': [ "$$this.v.B", 10 ] }
]
}
}
}
} },
{ '$addFields': {
't_s': '$fields.k'
} }
])
2. найти начало t
с, у которых B
больше 10 для данного _id
db.collection.aggregate([
{ '$match': { '_id': "xyz" } },
{ '$addFields': {
'fields': {
'$filter': {
'input': '$fields',
'cond': {
'$and': [
{ '$ne': [ { '$type' : "$$this.v.B" }, 'missing'] },
{ '$gt': [ "$$this.v.B", 10 ] }
]
}
}
}
} },
{ '$addFields': {
'start_times': '$fields.v.start'
} }
])
3. найти _id документов, в которых есть хотя бы один B ТС
db.collection.aggregate([
# convert root dynamic fields to key/value pair array
{ '$addFields': {
'fields': { '$objectToArray': '$$ROOT' }
} },
# filter all documents where size of array of Bs >= 1
{ '$match': {
'$expr': {
'$gte': [
{ '$size': '$fields.v.B' },
1
]
}
} },
# get array of _ids
{ '$addFields': {
'ids': {
'$filter': {
'input': '$fields',
'cond': { '$eq': [ '$$this.k', '_id' ] }
}
}
} },
# reshape field
{ '$addFields': {
'ids': '$ids.v'
} }
])