#php #mongodb #mongodb-query #aggregation-framework
#php #mongodb #mongodb-запрос #агрегация-фреймворк
Вопрос:
У меня есть этот набор данных в mongo
{
_id: {
question_id: 3
},
data: {
answer: 11,
count: 114,
result: [
{
_id: 3,
question: "What is your age group?",
options: [
{
id: 10,
option: "<18"
},
{
id: 11,
option: "18-24"
},
{
id: 12,
option: "24-35"
},
{
id: 13,
option: ">35"
}
],
type: "Radio"
}
]
}
},
Здесь я хотел бы выполнить equals to
проверку между answer
и result.options.id
, и если значение совпадает, оно должно вернуть result.options.option
Чтобы желаемый результат был
{
_id: {
question_id: 3
},
data: {
answer:'18-24',
count: 114,
}
},
До сих пор я пробовал это
'$project'=>[
'res'=>[
'$map'=>[
'input'=>'$data.result.options',
'as'=>'dt',
'in'=>[
'$cond'=>[
'if'=>[
'$eq'=>[
'$$dt.id',
'$data.answer'
]
],
'then'=>'$$dt.option',
'else'=>'$$dt.id'
]
]
]
]
]
Любой ключ к пониманию того, что я делаю неправильно. Мой код всегда возвращает оператор else
Ответ №1:
Вы были близки к истине, но есть пара вещей, которые не совсем верны:
[ '$project'=> [
'data' => [
'answer' => [
'$let' => [
'vars' => [
'res' => [
'$reduce' => [
'input' => '$data.result.options',
'initialValue' => [],
'in' => [ '$concatArrays': [ '$$value', '$$this' ] ]
]
]
],
'in' => [
'$arrayElemAt' => [
'$$res.option',
[ '$indexOfArray': [ '$$res.id', '$data.answer' ] ]
]
]
]
],
'count' => '$data.count'
]
]]
Путь к '$data.result.options'
фактически находится внутри вложенных массивов, поэтому для того, чтобы любые «операции с массивом» работали с внутренним значением 'options'
, вам нужно «сгладить» эту структуру массива в отдельный массив.
Для этого вам следует использовать $reduce
наряду с $concatArrays
. Это также продемонстрировано в $let
блоке, поскольку вы хотите использовать этот «результирующий массив» в некоторых последующих операциях.
Поскольку самый простой способ извлечь одно значение — это найти соответствующий индекс массива через $indexOfArray
to 'data.answer'
, а затем извлечь 'option'
значение из вашего «результирующего массива», обработанного ранее для этого значения, используя $arrayElemAt
, конечно, указание на соответствующий «индекс».
$indexOfArray
Оператор здесь надежен до тех пор, пока у вас всегда будет ответ, соответствующий 'data.answer'
значению, присутствующему в массиве document.