Как получить встроенный документ внутри коллекции MongoDB?
У меня есть сборник Notebook с встроенным документом массива, называемым Notes. Образец
выглядит так, как показано ниже.
{
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"),
"name" : "MongoDB",
"notes" : [
{
"title" : "Hello MongoDB",
"content" : "Hello MongoDB"
},
{
"title" : "ReplicaSet MongoDB",
"content" : "ReplicaSet MongoDB"
}
]
}
Я хочу узнать только заметку с названием "Hello MongoDB". Я не понимаю, что должно
- это запрос. Может кто-нибудь мне помочь.
Ответы
Ответ 1
Устаревший ответ: см. другие ответы.
Я не верю, что вы спрашиваете, по крайней мере, без какого-либо сокращения карты?
Смотрите здесь: Фильтрация встроенных документов в MongoDB
Этот ответ подсказывает, что вы меняете свою схему, чтобы лучше соответствовать тому, как вы хотите работать с данными.
Вы можете использовать либо "точечную нотацию", либо $elemMatch, чтобы вернуть правильный документ с соответствующим названием "примечания"...
> db.collection.find({ "notes.title" : "Hello MongoDB"}, { "notes.title" : 1"});
или...
> db.collection.find({ "notes" : { "$elemMatch" : { "title" : "Hello MongoDB"} }});
Но вы вернете весь массив, а не только элемент массива, вызвавший совпадение.
Кроме того, что-то, о чем нужно подумать... с вашей текущей настройкой, будет трудно выполнять какие-либо операции над элементами в массиве.
Если вы не измените свою схему (как ответ, связанный с предложениями)... Я бы подумал о добавлении "идентификаторов" к каждому элементу массива, чтобы вы могли делать такие вещи, как если бы это было легко удалить.
Ответ 2
Вы можете сделать это с версией mongo выше 2.2
запрос выглядит следующим образом:
db.coll.find({ 'notes.title': 'Hello MongoDB' }, {'notes.$': 1});
вы можете попробовать с помощью $elemMatch
как Джастин Дженкинс
Ответ 3
Вы можете сделать это в MongoDb версии 3.2+ с агрегацией.
Query:
db.Notebook.aggregate(
{
$project: {
"notes": {
$filter: {
input: "$notes",
as: "note",
cond: {
$eq: [ "$$note.title", "Hello MongoDB" ]
}
}
}
}
}
)
Результат:
{
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"),
"notes" : [
{
"title" : "Hello MongoDB",
"content" : "Hello MongoDB"
}
]
}
$$, используемый здесь для доступа к переменной. Я использовал здесь для доступа к вновь созданной переменной note
внутри $filter
.
Дополнительную информацию вы можете найти в официальной документации $filter, $eq и $$.
$filter: Выбирает подмножество массива для возврата на основе указанного условия. Возвращает массив только с теми элементами, которые соответствуют условию. Возвращенные элементы находятся в исходном порядке.
$eq: Сравнивает два значения и возвращает true/false, когда значения эквивалентны или нет (...).
$$: Переменные могут содержать данные типа BSON. Чтобы получить доступ к значению переменной, используйте строку с именем переменной с префиксом двойного доллара ($$).
Примечание:
Ответ Джастина Дженкина устарел, и ответ kop здесь не возвращает несколько документов из коллекции. С помощью этого запроса агрегации вы можете при необходимости возвращать несколько документов.
Мне это нужно и я хотел опубликовать сообщение, чтобы помочь кому-то.
Ответ 4
Вы можете использовать $или $elemMatch. Оператор $и оператор $elemMatch проектируют подмножество элементов из массива на основе условия.
Оператор проекции $elemMatch принимает явный аргумент условия. Это позволяет проецировать на основе условия, не входящего в запрос.
db.collection.find(
{
// <expression>
},
{
notes: {
$elemMatch: {
title: 'Hello MongoDB'
}
},
name: 1
}
)
Оператор $реализует элементы массива на основе некоторого условия из оператора запроса.
db.collection.find(
{
'notes.title': 'Hello MongoDB'
},
{
'notes.title.$': 1,
name: 1
}
)
Ответ 5
Вы можете выполнить запрос следующим образом:
db.coll.find({ 'notes.title': 'Hello MongoDB' });
Вы также можете обратиться к docs для более подробной информации.