#arrays #mongodb
#массивы #mongodb
Вопрос:
У меня возникли проблемы с запросом коллекции MongoDB с массивом внутри.
Вот структура моей коллекции, которую я запрашиваю. Это одна запись:
{
"_id": "abc123def4567890",
"profile_id": "abc123def4567890",
"image_count": 2,
"images": [
{
"image_id": "ABC123456789",
"image_url": "images/something.jpg",
"geo_loc": "-0.1234,11.234567890",
"title": "A Title",
"shot_time": "01:23:33",
"shot_date": "11/22/2222",
"shot_type": "scenery",
"conditions": "cloudy",
"iso": 16,
"f": 2.4,
"ss": "1/545",
"focal": 6.0,
"equipment": "",
"instructions": "",
"upload_date": 1234567890,
"update_date": 1234567890
},
{
"image_id": "ABC123456789",
"image_url": "images/something.jpg",
"geo_loc": "-0.1234,11.234567890",
"title": "A Title",
"shot_time": "01:23:33",
"shot_date": "11/22/2222",
"shot_type": "portrait",
"conditions": "cloudy",
"iso": "16",
"f": "2.4",
"ss": "1/545",
"focal": "6.0",
"equipment": "",
"instructions": "",
"upload_date": 1234567890,
"update_date": 1234567890
}
]
}
Простите за форматирование, я не знал, как еще это показать.
Как вы можете видеть, это профиль с серией изображений в массиве под названием «изображения», и в нем есть 2 изображения. Каждый из элементов массива «изображения» содержит объект атрибутов для изображения (URL, заголовок, тип и т.д.).
Все, что я хочу сделать, это вернуть элемент object, атрибуты которого соответствуют определенным критериям:
Выберите объект из изображений, который имеет shot_type = «scenery»
Я попытался сделать это как можно проще, поэтому начал с:
find( { "images.shot_type": "scenery" } )
Это возвращает всю запись и оба изображения внутри. Итак, я попробовал проекцию, но не смог выделить отдельный объект в массиве (в данном случае объект в позиции 0) и вернуть его.
Я думаю, что ответ лежит в проекции, но я не уверен.
Я уже несколько часов просматриваю документы MongoDB и не могу найти вдохновения. Я прочитал о $ elemMatch, $ и других операторах массива, похоже, ничто не позволяет вам выделить элемент массива на основе данных внутри. Я тоже просматривал эту страницу https://docs.mongodb.com/manual/tutorial/query-arrays / Все еще не могу разобраться в этом.
- Кто-нибудь может оказать помощь?
- Допустил ли я ошибку, используя ‘$ push’ для заполнения моего поля изображений (превращая его в массив) вместо использования ‘$ set’, который превратил бы его во встроенный документ? Имело бы это значение?
Ответ №1:
Использование агрегации:
db.collection.aggregate({
$project: {
_id: 0,
"result": {
$filter: {
input: "$images",
as: "img",
cond: {
$eq: [
"$img.shot_type",
"scenery"
]
}
}
}
}
})
Игровая площадка
Комментарии:
1. Спасибо вам за это. Мне нужно больше узнать об агрегации. Я думал, что смогу выполнить этот запрос с помощью простого «find». Я был неправ.
2. Пожалуйста. Есть бесплатные курсы по mongo db. Возьмите хотя бы один из этих @Phfog. Занимает 1 или 2 дня. Научитесь использовать
$match
и$project
и$unwind
этого почти достаточно
Ответ №2:
Вы можете использовать $elemMatch
таким образом (упрощенный запрос):
db.collection.find({
"profile_id": "1",
},
{
"images": {
"$elemMatch": {
"shot_type": 1
}
}
})
Вы можете использовать два объекта в find
запросе. Первый отфильтрует весь документ и получит только те, значение которых profile_id
равно 1. Вы можете пропустить этот этап и использовать только { }
в том случае, если вы хотите выполнить поиск по всей коллекции.
Затем другой объект использует $elemMatch
для получения только элемента, значение которого shot_type
равно 1.
Проверьте пример здесь