Поиск документов с массивами, не содержащими документ с определенным значением поля в MongoDB

Я пытаюсь найти все документы, которые не содержат хотя бы один документ с определенным значением поля. Например, вот пример коллекции:

{  _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 } } })

Нужно ли вообще выполнить это с основными операторами?

Ответы

Ответ 1

Использование $nin будет работать, но у вас синтаксис неправильный. Должен быть:

db.collection.find({'docs.foo': {$nin: [1]}})

Ответ 2

Используйте оператор $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 является излишним и, возможно, имеет низкую производительность.