2012-04-06 3 views
29

У меня есть коллекция Notebook, которая имеет встроенный документ массива, называемый Notes. ОбразецКак получить встроенный документ внутри коллекции MongoDB?

документ выглядит, как показано ниже.

{ 
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"), 
"name" : "MongoDB", 
"notes" : [ 
      { 
       "title" : "Hello MongoDB", 
       "content" : "Hello MongoDB" 
      }, 
      { 
       "title" : "ReplicaSet MongoDB", 
       "content" : "ReplicaSet MongoDB" 
      } 
     ] 
} 

Я хочу найти только примечание, которое имеет название «Hello MongoDB». Я не получаю, что должно быть

будет запрос. Может кто-нибудь мне помочь.

ответ

36

Устаревший ответ: см. Другие ответы.


Я не верю в то, что вы спрашиваете, возможно, по крайней мере, без какой-то карта-свертка может быть?

Смотрите здесь: Filtering embedded documents in MongoDB

Этот ответ предлагает вам изменить схему, чтобы лучше удовлетворить, как вы хотели бы работать с данными.

Вы можете использовать либо «точечную нотацию» или $ elemMatch вернуть правильный, документ, который имеет соответствующий «примечание название» ...

> db.collection.find({ "notes.title" : "Hello MongoDB"}, { "notes.title" : 1"}); 

или ...

> db.collection.find({ "notes" : { "$elemMatch" : { "title" : "Hello MongoDB"} }}); 

Но вы вернете весь массив, а не только элемент массива, который вызвал совпадение.

Кроме того, что-то, о чем нужно подумать ... с вашей текущей настройкой, будет трудно выполнять какие-либо операции над элементами в массиве.

Если вы не меняете свою схему (как ответ, связанный с предложениями) ... Я бы подумал о добавлении «идентификаторов» к каждому элементу массива, чтобы вы могли делать такие вещи, как если бы это было легко удалить.

-3

Вы можете выполнить запрос так:

db.coll.find({ 'notes.title': 'Hello MongoDB' }); 

Вы также можете обратиться к docs для более подробной информации.

+8

Hummm Я верю, что спрашивается, как вернуть ТОЛЬКО ** примечание ** с помощью «Hello MongoDB» в качестве ** title **, ваш пример вернет весь документ * вместе с массивом заметок! –

73

Вы можете сделать это с Монго версии 2.2 выше,

запрос так:

db.coll.find({ 'notes.title': 'Hello MongoDB' }, {'notes.$': 1}); 

вы можете попробовать с $elemMatch как Джастин Дженкинс

+5

Это должен быть правильный ответ. – KIC

+3

Это вернет _id родительского документа вместе с внедренным объектом, если вы не исключите _id из запроса: ... {'notes. $': 1, '_id': 0}); – Ushox

+0

Где находится документация для этой структуры запросов, которую вы используете? – etech

0

Вы можете использовать $ или $ 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 
    } 
) 
2

Вы можете сделать это в версии 3.2+ MongoDb с агрегацией.

Запрос:

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 и $$.

$ Фильтр: Выбирает подмножество массива, чтобы вернуться на основе заданного условия. Возвращает массив только с теми элементами, которые соответствуют условию. Возвращенные элементы находятся в исходном порядке.

$ eq: Сравнивает два значения и возвращает true/false, когда значения эквивалентны или нет (...).

$$: Переменные могут содержать данные типа BSON. Чтобы получить доступ к значению переменной, используйте строку с именем переменной с префиксом двойного доллара ($$).


Примечание:

ответ Джастин Дженкин является устаревшим и ответ Коп здесь не возвращает несколько документов из коллекции. С помощью этого запроса агрегации вы можете вернуть несколько документов, если это необходимо.

Мне это было нужно и я хотел бы опубликовать сообщение, чтобы помочь кому-то.