Ответ 1
Использование $nin
будет работать, но у вас синтаксис неправильный. Должен быть:
db.collection.find({'docs.foo': {$nin: [1]}})
Я пытаюсь найти все документы, которые не содержат хотя бы один документ с определенным значением поля. Например, вот пример коллекции:
{ _id : 1,
docs : [
{ foo : 1,
bar : 2},
{ foo : 3,
bar : 3}
]
},
{ _id : 2,
docs : [
{ foo : 2,
bar : 2},
{ foo : 3,
bar : 3}
]
}
Я хочу найти каждую запись, где в блоке документов нет документа, который не содержит по крайней мере одной записи с foo = 1. В приведенном выше примере должен быть возвращен только второй документ.
Я пробовал следующее, но это только говорит мне, есть ли какие-либо, которые не соответствуют (который возвращает документ 1.
db.collection.find({"docs": { $not: {$elemMatch: {foo: 1 } } } })
UPDATE: Выполненный запрос действительно работает. Сколько раз случалось, мои данные были неправильными, а не мой код.
Я также посмотрел на оператор $ nin, но примеры показывают, когда массив содержит список примитивных значений, а не дополнительный документ. Когда я попытался сделать это с чем-то вроде следующего, он ищет EXACT-документ, а не только поле foo, которое я хочу.
db.collection.find({"docs": { $nin: {'foo':1 } } })
Нужно ли вообще выполнить это с основными операторами?
Использование $nin
будет работать, но у вас синтаксис неправильный. Должен быть:
db.collection.find({'docs.foo': {$nin: [1]}})
Используйте оператор $ne
:
db.collection.find({'docs.foo': {$ne: 1}})
Обновление: я бы посоветовал не использовать $nin
в этом случае.
{'docs.foo': {$ne: 1}}
принимает все элементы docs
, и для каждого из них он проверяет, равно ли поле foo
1 или нет. Если он находит совпадение, он отбрасывает документ из списка результатов.
{'docs.foo': {$nin: [1]}}
принимает все элементы docs
, и для каждого элемента он проверяет, совпадает ли его поле foo
любым из элементов массива [1]
. Это декартово произведение, вы сравниваете массив с другим массивом, каждый элемент каждого элемента. Хотя MongoDB может быть умным и оптимизировать этот запрос, я предполагаю, что вы используете только $nin
потому что "он что-то делает с массивами". Но если вы поймете, что вы здесь делаете, вы поймете, что $nin
является излишним и, возможно, имеет низкую производительность.