Лучший способ создать выражение манго, которое никогда не совпадает

То, что я ищу, как-то эквивалентно выполнению в SQL:

WHERE 1 = 0

Я ищу такую ​​вещь, потому что я строю типовой DSL для выполнения запросов в моем домене, поддерживая союзы и дизъюнкции. Иногда бывает проще добавить запрос, который никогда не соответствует чему-либо, вместо того, чтобы иметь дело с ним в коде.

Например, в моем usecase:

StampleFilters().underCategoryIds(sharedCategoryIds.toList)

В этом случае он работает не так, как ожидалось, потому что sharedCategoryIds пуст, поэтому он вызывает запрос $(), который ничего не фильтрует. Для пустого списка я предпочел бы построить запрос, который никогда ничего не возвращает.

Есть ли простой способ сделать такую ​​вещь без какого-либо влияния на производительность?

Возможно, я мог бы добавить некоторый запрос, например { somefield: unexistingvalue }, но мне интересно, нет ли лучшего.

Edit

Я ожидаю, что выражение будет составным. Я имею в виду, что он должен работать в таких запросах, как $or(exp1,exp2,exp3), где exp1 означает пример, который никогда не соответствует.

Если у вас есть какое-либо предложение, было бы неплохо объяснить, почему один лучше других и как он влияет на производительность механизма запроса (или нет)

2 ответа

Я думаю, что лучший способ достичь желаемого - добавить {_id : -1}

db.coll.find({a : 1}) будет преобразовано в db.coll.find({a : 1, _id : -1}). Это проще, чем все решения shx2 (за исключением последнего с noScan, который хорош).

Кроме того, поле _id уже является первичным индексом, поэтому оно быстро осознает, что в коллекции нет такого поля _id.

P.S., если кто-то будет настолько умным, чтобы называть их _id как -1, тогда вы можете сделать {_id : NaN}. Если будет _id = NaN, вам, скорее всего, придется перестроить ваше приложение.


Я придумал несколько способов добиться этого:

  • "P &! P": { $and: [ {X:0}, {X:{$ne:0}} ] }
  • Не может быть "$ in" в пустом списке: { X: {$in: []} }
  • Ничто не может быть таким длинным { X: {$size: 9999999999999999} }
  • " noScan": db.coll.find({})._addSpecial("$maxScan", 0)

EDIT:

  • еще один, используя $where: { $where: function() {return 0} }

licensed under cc by-sa 3.0 with attribution.