Вопрос 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 }}});
>
Документы не были возвращены.
Ответы
Ответ 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, тогда вы должны включить его в свой запрос.
Имейте в виду, что все предложения запроса объединены по умолчанию, если вы не используете оператор $или.