一般情况下如果检索数据排序操作,需要创建索引来提高查询速度,所以先看看创建索引
db.collection.ensureIndex({key:1})
其中key为要创建的索引字段,1指定为升序,-1时为降序
例子:
> db.c1.ensureIndex({"name":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.c1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "db1.c1"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "name_1",
"ns" : "db1.c1"
}
]
使用索引查询,其中hint说明强制使用索引,当然也可以用逗号隔开用多个索引
> var cursor=db.c1.find({"name":"a"})
> cursor.explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db1.c1",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "a"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"a\", \"a\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "g-dragon1-PC",
"port" : 27017,
"version" : "3.4.5",
"gitVersion" : "520b8f3092c48d934f0cd78ab5f40fe594f96863"
},
"ok" : 1
}
> var cursor=db.c1.find({"name":"a"}).hint({"name":1})
> cursor.explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db1.c1",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "a"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"a\", \"a\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "g-dragon1-PC",
"port" : 27017,
"version" : "3.4.5",
"gitVersion" : "520b8f3092c48d934f0cd78ab5f40fe594f96863"
},
"ok" : 1
其他索引选项:
Parameter | Type | Description |
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。 |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
dropDups | Boolean | 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. |
sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. |
expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 |
v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 |
weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
比如创建唯一索引:
> db.c1.find()
{ "_id" : ObjectId("5958d8cda6e810ff1933a6dd"), "name" : "china" }
{ "_id" : ObjectId("5958ef83068141c2055cce10"), "name" : "usa", "age" : 1 }
{ "_id" : ObjectId("5961d1b3d233e9d684bd0298"), "name" : "usa", "age" : "aaa" }
{ "_id" : ObjectId("5961d22dd233e9d684bd0299"), "name" : "usa2", "age" : 2 }
{ "_id" : ObjectId("598557b9dc51aa3086b6def2"), "name" : "a" }
> db.c1.ensureIndex({name:1,"age":1},{unique:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
预热完了,现在看排序,语法
db.collection.find().sort({key:1})
比如讲叙查看:
> db.c1.find()
{ "_id" : ObjectId("5958d8cda6e810ff1933a6dd"), "name" : "china" }
{ "_id" : ObjectId("5958ef83068141c2055cce10"), "name" : "usa", "age" : 1 }
{ "_id" : ObjectId("5961d1b3d233e9d684bd0298"), "name" : "usa", "age" : "aaa" }
{ "_id" : ObjectId("5961d22dd233e9d684bd0299"), "name" : "usa2", "age" : 2 }
{ "_id" : ObjectId("598557b9dc51aa3086b6def2"), "name" : "a" }
> db.c1.find({},{"name":1,_id:0}).sort({"name":-1})
{ "name" : "usa2" }
{ "name" : "usa" }
{ "name" : "usa" }
{ "name" : "china" }
{ "name" : "a" }
最后,看看limit,skip,使用它可以实现分页操作
linut相当于mysql的limit,返回指定行记录,语法
db.coll.find().limit(number)
比如:
> db.c1.find()
{ "_id" : ObjectId("5958d8cda6e810ff1933a6dd"), "name" : "china" }
{ "_id" : ObjectId("5958ef83068141c2055cce10"), "name" : "usa", "age" : 1 }
{ "_id" : ObjectId("5961d1b3d233e9d684bd0298"), "name" : "usa", "age" : "aaa" }
{ "_id" : ObjectId("5961d22dd233e9d684bd0299"), "name" : "usa2", "age" : 2 }
{ "_id" : ObjectId("598557b9dc51aa3086b6def2"), "name" : "a" }
> db.c1.find({},{"name":1,_id:0}).limit(2)
{ "name" : "china" }
{ "name" : "usa" }
skip非那根发做为跳过的记录数
db.coll.find().limit(number).skip(number)
举例:
> db.c1.find()
{ "_id" : ObjectId("5958d8cda6e810ff1933a6dd"), "name" : "china" }
{ "_id" : ObjectId("5958ef83068141c2055cce10"), "name" : "usa", "age" : 1 }
{ "_id" : ObjectId("5961d1b3d233e9d684bd0298"), "name" : "usa", "age" : "aaa" }
{ "_id" : ObjectId("5961d22dd233e9d684bd0299"), "name" : "usa2", "age" : 2 }
{ "_id" : ObjectId("598557b9dc51aa3086b6def2"), "name" : "a" }
> db.c1.find({},{"name":1,_id:0}).limit(2).limit(1)
{ "name" : "china" }
> db.c1.find({},{"name":1,_id:0}).limit(2).skip(1)
{ "name" : "usa" }
{ "name" : "usa" }
> db.c1.find({},{"name":1,_id:0}).limit(2).skip(2)
{ "name" : "usa" }
{ "name" : "usa2" }
> db.c1.find({},{"name":1,_id:0}).skip(2)
{ "name" : "usa" }
{ "name" : "usa2" }
{ "name" : "a" }
联合使用limit和skip就相当于分页查询