2014-10-09 7 views
0

Скажем, у меня есть коллекция с документами, как показано ниже:Выбор записей, когда атрибута нет?

{ 
    title: "test1", 
    items: 
    [ 
     {id: 1, sub_id: 23, value:"some value"}, 
     {id: 2, value:"some value"} 
    ] 
}, 
{ 
    title: "test2", 
    items: 
    [ 
     {id: 4, sub_id: 34, value:"blah"}, 
     {id: 5, sub_id: 56, value:"whatever"}, 
    ] 
} 

И я хочу, чтобы выбрать, где атрибут sub_id не существует и id атрибут делает существует. Если я выполнить запрос:

db.myCollection.find({"items.sub_id": {$exists: false}}) 

он возвращает запись я хочу (документ с названием test1), но когда я запускаю этот запрос:

db.myCollection.find({"items.sub_id": {$exists: false}, "items.id": {$exists:true}}) 

она ничего не возвращает. Если мой второй запрос не возвращает те же результаты, что и первый запрос

ответ

1

На самом деле ваш первый запрос не может вернуть результаты из образца, который вы даете. Причина в том, что ни один из документов не имеет элементов, которые не содержат свойства «sub_id». Таким образом, в первом документе, в то время как второй элемент массива не имеет свойства, первый имеет один, поэтому условие на самом деле является ложным. Немного забавная вещь с $exists и ложным тестом.

Для того, чтобы выполнить эту работу, вам необходимо сравнить условия для отдельных элементов массива. Это означает, что вам нужно $elemMatch оператор:

db.myCollection.find({ 
    "items": { 
     "$elemMatch": { 
      "id": { "$exists": true }, 
      "sub_id": { "$exists": false } 
     } 
    } 
}) 

И правильно выбирает документ, который имеет элемент массива, где есть свойство «идентификатор», но не свойство «sub_id».

Благодаря тому, как $exists пересекающей документ соответствует условию, то же самое относится к одному элементу, а также, и, следовательно, является одним из случаев, которые вы используете $elemMatch только для одного поля:

db.myCollection.find({ 
    "items": { 
     "$elemMatch": { 
      "sub_id": { "$exists": false } 
     } 
    } 
}) 

Таким образом, чтобы инструмент применялся к элементу массива, где, конечно, один элемент не обладает свойством и, следовательно, было хотя бы одно совпадение, и документ возвращается.