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

Вопрос Mongo Query $gt, $lt

У меня есть запрос ниже. Я хочу получить пункты между 4 и 6, поэтому только один: 1 должен совпадать, потому что он имеет значение 5 в b.

> db.test.find({ b : { $gt :  4  }, b: {$lt : 6}});
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
>

Может ли кто-нибудь объяснить, почему: 2 соответствует этому запросу? Я не могу понять, почему он возвращается.

Я также пробовал то, что было указано в учебнике, но id, похоже, не работал:

> db.test.find({ b : { $gt :  4, $lt : 6}});
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
>

И этот, чтобы избежать путаницы в отношении GT/GTE

> db.test.find({b: {$gt: 4.5, $lt: 5.5}});
{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
>

нужно вернуть только a: 1.

Как я уже сказал, я попробовал $elemMatch, но он тоже не работал (objectIds разные, потому что я на другой машине)

> db.test.find();
{ "_id" : ObjectId("4d5a24a5e82e00000000433f"), "a" : 1, "b" : [ 2, 3, 4, 5 ] }
{ "_id" : ObjectId("4d5a24bbe82e000000004340"), "a" : 2, "b" : [ 2, 4, 6, 8 ] }
> db.test.find({b: {$elemMatch: {$gt : 4, $lt: 6 }}});
>

Документы не были возвращены.

4b9b3361

Ответ 1

Это действительно запутанная тема. Я работаю в 10gen, и мне пришлось потратить некоторое время, обворачивая вокруг себя;)

Проследите, как обработчик запросов обрабатывает этот запрос.

Здесь снова запрос:

> db.test.find({ b : { $gt :  4, $lt : 6}});

Когда он попадает в запись, которая кажется, что она не должна совпадать...

{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] }

Совпадение не выполняется против каждого элемента массива, а скорее против массива в целом.

Сравнение выполняется в три этапа:

Шаг 1: найдите все документы, где b имеет значение больше 4

b: [2,4,6,8] соответствует, поскольку 6 и 8 больше 4

Шаг 2: найдите все документы, где b имеет значение менее 6

b: [2,4,6,8] соответствует, потому что 2 и 4 меньше 6

Шаг 3. Найдите набор документов, которые совпадают на обоих этапах 1 и 2.

Документ с b: [2,4,6,8] соответствует двум шагам 1 и 2, поэтому он возвращается как совпадение. Обратите внимание, что результаты также дедуплицируются на этом этапе, поэтому один и тот же документ не будет возвращен дважды.

Если вы хотите, чтобы ваш запрос применялся к отдельным элементам массива, а не к массиву в целом, вы можете использовать оператор $elemMatch. Например

> db.temp.find({b: {$elemMatch: {$gt: 4, $lt: 5}}})
> db.temp.find({b: {$elemMatch: {$gte: 4, $lt: 5}}})
  { "_id" : ObjectId("4d558b6f4f0b1e2141b66660"), "b" : [ 2, 3, 4, 5, 6 ] }

Ответ 2

$gt

Syntax: {field: {$gt: value} }

например:

db.inventory.find( { qty: { $gt: 20 } } )

Syntax: {field: {$lt: value} }

например:

db.inventory.find( { qty: { $lt: 20 } } )

ЭГ2:

db.inventory.find({ qty : { $gt :  20, $lt : 60}});

Ответ 3

.find( {$and:[ {b:{$gt:4}}, {b:{$lt:6}} ]} )

Ответ 4

Потому что вы не проверяли документацию.

См.

http://www.mongodb.org/display/DOCS/Advanced+Queries

и проверьте "диапазоны" на странице.

Правильно ли ваш синтаксис запроса (сравните с примером)

и ваша "почему a: 2" часть вопроса имеет смысл, поскольку "a" не участвует в вашем запросе. Если вы хотите найти a: 1, тогда вы должны включить его в свой запрос.

Имейте в виду, что все предложения запроса объединены по умолчанию, если вы не используете оператор $или.