$ или операция для сопоставления одного и того же элемента в двух разных массивах

#mongodb #express #aggregation-framework

#mongodb #выразить #агрегация-фреймворк

Вопрос:

Допустим, у меня есть два разных массива в двух разных документах, а именно carPolicies[] и paPolicies[] . Очевидно, существуют policy объекты, содержащие ключ agent .

 [
  {
    "_id": "_id",
    "name": "qwe",
    "password": "pw",
    "carPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
    ],
    "paPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
    ]
  },


  {
    "_id": "_id",
    "name": "rty",
    "password": "wp",
    "carPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
    ],
    "paPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
      {
        "policy": {
          "agent": "99"
        }
      }
    ]
  }
]
  

Если я выполню запрос, подобный приведенному ниже, он вернет мне политики только из carPolicies[] where agent : 47.

 db.collection('users').aggregate([
    
             
    
            // get just the documents that contain an agent key where agent is  === 47 
            { $match: { 'carPolicies.policy.agent': req.params.name } },
            {
                $project: {
                    policy: {
                        $filter: {
                            input: '$carPolicies.policy',
                            as: 'police',
                            cond: { $eq: ['$$police.agent', req.params.name ]}
                        }
                    }
                }
            }
        
        ])
  

Однако я хотел бы изменить тот же запрос, чтобы также проверить, paPolicies[] где agent : 47. Как бы я добавил, $or чтобы иметь возможность проверять оба массива в одном запросе, где agent равно 47? Или есть другой оператор, который больше подходит для моего варианта использования?

Мой ожидаемый результат должен выводить:

 [
  {
    "policy": [
      {
        "agent": "47"
      }
    ]
  },
  {
    "policy": [
      {
        "agent": "47"
      }
    ]
  },
{
    "policy": [
      {
        "agent": "47"
      }
    ]
  },
  {
    "policy": [
      {
        "agent": "47"
      }
    ]
  }
]
  

В выходных данных должно быть 4 политики, поскольку в моем примере только 4 политики имеют agent = 47, где одна из политик имеет agent = 99, которые не должны быть извлечены.

Комментарии:

1. куда вы хотите добавить or условие в $match или $ filter?

2. @turivishal что вы имеете в виду?

3. я имею в виду , где вы хотите проверить условие для paPolicies ? в конвейере $match или в фильтре конвейера $ project?

4. @turivishal предпочтительно в конвейере $match.

Ответ №1:

Вы можете попробовать,

  • добавьте условие в $match с помощью $or
  • добавить paPolicies.policy в качестве входных данных в фильтр, используя и $concatArrays
  • $unwind деконструировать policy массив
  • $project для преобразования policy в массив
 db.collection.aggregate([
  {
    $match: {
      $or: [
        { "carPolicies.policy.agent": req.params.name },
        { "paPolicies.policy.agent": req.params.name }
      ]
    }
  },
  {
    $project: {
      policy: {
        $filter: {
          input: {
            $concatArrays: ["$carPolicies.policy", "$paPolicies.policy"]
          },
          as: "police",
          cond: { $eq: ["$$police.agent", req.params.name] }
        }
      }
    }
  },
  { $unwind: "$policy" },
  {
    $project: {
      _id: 0,
      policy: ["$policy"]
    }
  }
])
  

Игровая площадка

Комментарии:

1. Я проверил вашу ссылку на игровую площадку mongo, она не извлекала политики из paPolicies[] where agent равно 47 как вы можете видеть из моего кода, у меня есть $filter где input находится $carPolicies.policy конкретно. Что, если вместо этого вы сделаете это в $filter ?

2. да, именно поэтому я спросил вас, можете ли вы добавить ожидаемый результат в свои данные

3. конечно, я добавлю это в свой вопрос для уточнения. Спасибо.

4. вам нужно убедиться, что _id — это тот же идентификатор, который у вас есть в коллекции, и проверить его идентификатор объекта или идентификатор объекта string в коллекции.

5. Да, у меня есть. Я уже устранил проблему. Мне нужно было явно добавить в мой запрос, что _id является ObjectId.