数组和范围查询的注意点

先插入几条数据,如下:

db.man.insert([{"age":5},{"age":10},{"age":15},{"age":25},{"age":[12]},{"age":[12,13]},{"age":[18,21]},{"age":[5,25]}])

db.man.find()

{ "_id" : ObjectId("5899baa741d79c19ed14f7a4"), "age" : 5 }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a5"), "age" : 10 }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a6"), "age" : 15 }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a7"), "age" : 25 }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a8"), "age" : [ 12 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a9"), "age" : [ 12, 13 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7aa"), "age" : [ 18, 21 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7ab"), "age" : [ 5, 25 ] }

(1)查询 10 < x < 20 的记录

db.man.find({"age":{"$gt":10 , "$lt":20}})

{ "_id" : ObjectId("5899baa741d79c19ed14f7a6"), "age" : 15 }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a8"), "age" : [ 12 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a9"), "age" : [ 12, 13 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7aa"), "age" : [ 18, 21 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7ab"), "age" : [ 5, 25 ] }

总结

文档中的标量(非数组元素)必须与查询条件中的每一条语句相匹配。例如,如果使用{“x”:{"$gt":10, "$lt":20}进行查询,只会匹配“X”键的值大于10并且小于20的文档。但是假如某个文档的x字段是一个数组,并且x的键的某一个元素与查询的任何一条语句相匹配【存在】,那么这个文档也会返回。

换一种写法

db.man.find({"age":{"$gt":10,"$lt":20}}).min({"age":10}).max({"age":20})

Error: error: {

           "waitedMS" : NumberLong(0),

           "ok" : 0,

           "errmsg" : "error processing query: ns=demo.manTree: $and\n    age $lt 20.0\n    age $gt 10.0\nSort: {}\nProj: {}\n planner returned error: unable to find relevant index for max/min query",

           "code" : 2

}

意思是需要建立索引

db.man.ensureIndex({"age":1})

{

          "createdCollectionAutomatically" : false,

          "numIndexesBefore" : 1,

          "numIndexesAfter" : 2,

          "ok" : 1

}

再次执行

db.man.find({"age":{"$gt":10,"$lt":20}}).min({"age":10}).max({"age":20})

{ "_id" : ObjectId("5899baa741d79c19ed14f7a8"), "age" : [ 12 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a9"), "age" : [ 12, 13 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a6"), "age" : 15 }

{ "_id" : ObjectId("5899baa741d79c19ed14f7aa"), "age" : [ 18, 21 ] }

db.man.find({"age":{"$elemMatch":{"$gt":10,"$lt":20}}})

{ "_id" : ObjectId("5899baa741d79c19ed14f7a8"), "age" : [ 12 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7a9"), "age" : [ 12, 13 ] }

{ "_id" : ObjectId("5899baa741d79c19ed14f7aa"), "age" : [ 18, 21 ] }

总结

1. 可以使用 “$elemMatch” 要求 Mongodb 同时使用查询条件中的两个语句 与 一个数组元素进行比较,并且该标签不会匹配非数组元素

2. 使用min和max时候一定要该字段添加索引,要不添加就会报错。


疑问:如果我只想查age为非数组的记录?

你可能感兴趣的:(数组和范围查询的注意点)