Подтвердить что ты не робот

Запрос Mongodb с полями в тех же документах

У меня есть следующий json.

{
  "a1": {"a": "b"},
  "a2": {"a": "c"}
}

Я хочу запросить все документы, где a1 не равно a2 в одном документе.

Как я могу это сделать?

4b9b3361

Ответ 1

Вы можете использовать $where:

db.myCollection.find( { $where: "this.a1.a != this.a2.a" } )

Однако имейте в виду, что это будет не очень быстро, потому что ему придется развернуть движок java script и выполнить итерацию каждого документа и проверить условие для каждого.

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

Ответ 2

Чтобы избежать использования JavaScript, используйте структуру агрегации:

db.myCollection.aggregate([
  {"$match":{"a1":{"$exists":true},"a2":{"$exists":true}}},
  {"$project": {
      "a1":1,
      "a2":1,
      "aCmp": {"$cmp":["$a1.a","$a2.a"]}
    }
  },
  {"$match":{"aCmp":0}}
])

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

Обновление (10 мая 2017 г.)

Я только понял, что мой ответ не ответил на вопрос, который хотел не равных ценностей (иногда я очень медленный). Это будет работать для этого:

db.myCollection.aggregate([
  {"$match":{"a1":{"$exists":true},"a2":{"$exists":true}}},
  {"$project": {
      "a1":1,
      "a2":1,
      "aEq": {"$eq":["$a1.a","$a2.a"]}
    }
  },
  {"$match":{"aEq": false}}
])

$ne можно использовать вместо $eq, если условие соответствия было изменено на true, но я считаю использование $eq с false более интуитивным.

Ответ 3

MongoDB использует Javascript в фоновом режиме, поэтому

{"a": "b"} == {"a": "b"}

будет false.

Итак, чтобы сравнить каждый, вы должны были бы a1.a == a2.a

Чтобы сделать это в MongoDB, вы должны использовать оператор $where

db.myCollection.find({$where: "this.a1.a != this.a2.a"});

Это предполагает, что каждый внедренный документ будет иметь свойство "a". Если это не так, все усложняется.