#mongodb #aggregate
Вопрос:
У меня есть 2 коллекции MongoDB, вот 2 примера моделей:
Коллекция пользователей:
{
_id: ObjectId,
available: Boolean,
province: String,
city: String,
[...]
}
Коллекция расстояний:
{
_id: ObjectId,
start_province: String,
start_city: String,
end_province: String,
end_city: String,
distance: Number
}
Мне нужно найти пользователей , используя следующий запрос {available: true}
, а затем использовать некоторые агрегаты для добавления для каждого пользователя документ расстояние поле, которое будет содержать значение, если существует соответствие между провинцией и городом пользователей и end_province / end_city от расстояния (start_province и start_city являются фиксированными значениями, определенными в JS, прежде чем этот стог).
Если есть совпадение, расстояние должно содержать значение расстояния, в противном случае 0 (или не определено).
Я думаю, что мне следует использовать $lookup и/или $addFields, но я еще недостаточно уверен в операторах агрегации, чтобы решить эту проблему.
Пример Результатов пользователей:
[
{
_id: ObjectId,
available: Boolean,
province: String,
city: String,
[...],
distance: Number
},
{...}
]
Спасибо за вашу помощь!
ИЗМЕНИТЬ: Добавление примеров данных по запросу:
Users
[
{name: 'John', available: true, province: 'Rome', city: 'Tivoli'},
{name: 'Difool', available: true, province: 'Rome', city: 'Ostia'},
{name: 'Paul', available: true, province: 'Rome', city: 'Rome'},
{name: 'Andrew', available: false, province: 'Rome', city: 'Grottaferrata'}
]
Distances
[
{start_province: 'Rome', start_city: 'Rome', end_province: 'Rome', end_city: 'Ostia', distance: 5},
{start_province: 'Rome', start_city: 'Rome', end_province: 'Rome', end_city: 'Tivoli', distance: 8}
]
Ожидаемые результаты от Пользователей
[
{name: 'John', available: true, province: 'Rome', city: 'Tivoli', distance: 8},
{name: 'Difool', available: true, province: 'Rome', city: 'Ostia', distance: 5},
{name: 'Paul', available: true, province: 'Rome', city: 'Rome', distance: 0}
]
Запрос фильтра:
{ available: true }
Пользователь.провинция должна совпадать с расстоянием.end_province
User.city должен совпадать с Distance.end_city.
В противном случае расстояние должно возвращать 0 или не определено. Спасибо.
Комментарии:
1. если вы добавите примеры данных и ожидаемых данных, было бы полезно лучше понять и иметь возможность протестировать запрос.
2. Отредактировано по запросу, спасибо!
3. Редактирование было очень хорошим! надеюсь, я сделал то, что ты хотел
4. это выглядит идеально! Спасибо!
Ответ №1:
Запрос
- фильтр для сохранения доступной
- присоединяйтесь, если
- Пользователь.провинция должна совпадать с расстоянием.end_province
- User.city должен совпадать с Distance.end_city.
- если не присоединено => расстояние=0, иначе получите расстояние от первого присоединенного документа
- снимите значения расстояний(результат соединения)
*если у вас есть mongodb
db.users.aggregate([
{
"$match": {
"available": {
"$eq": true
}
}
},
{
"$lookup": {
"from": "distances",
"let": {
"uprovince": "$province",
"ucity": "$city"
},
"pipeline": [
{
"$match": {
"$expr": {
"$and": [
{
"$eq": [
"$uprovince",
"$end_province"
]
},
{
"$eq": [
"$ucity",
"$end_city"
]
}
]
}
}
}
],
"as": "distances"
}
},
{
"$set": {
"distance": {
"$cond": [
{
"$eq": [
"$distances",
[]
]
},
0,
{
"$arrayElemAt": [
"$distances.distance",
0
]
}
]
}
}
},
{
"$unset": [
"distances"
]
}
])