#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[]
whereagent
равно 47 как вы можете видеть из моего кода, у меня есть$filter
гдеinput
находится$carPolicies.policy
конкретно. Что, если вместо этого вы сделаете это в$filter
?2. да, именно поэтому я спросил вас, можете ли вы добавить ожидаемый результат в свои данные
3. конечно, я добавлю это в свой вопрос для уточнения. Спасибо.
4. вам нужно убедиться, что _id — это тот же идентификатор, который у вас есть в коллекции, и проверить его идентификатор объекта или идентификатор объекта string в коллекции.
5. Да, у меня есть. Я уже устранил проблему. Мне нужно было явно добавить в мой запрос, что _id является ObjectId.