users
数据库中的classOne
集合中添加 1000000 条文档> use user
> for (var i = 1; i<= 1000000;i++) {
users.push({name: 'Lily_' + i, num: i })
}
> db.classOne.insert(users);
/* BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 1000000, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] })*/
复制代码
{num: 1000000}
文档的过程分析> db.classOne.find({num: 1000000}).explain(true)
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "user.classOne",
"indexFilterSet" : false,
"parsedQuery" : {...},
"winningPlan" : {
"stage" : "COLLSCAN", // 扫描全部的数据
"filter" : {...},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 365, // 本次查找执行时间的毫秒数
"totalKeysExamined" : 0,
"totalDocsExamined" : 1000000,
"executionStages" : {
...
},
"allPlansExecution" : [ ]
},
"serverInfo" : {
...
},
"ok" : 1
}
复制代码
从这个过程的解析对象中,咱们得知查找{num: 1000000}
文档,是经过COLLSCAN
方式扫描的,执行的时间为 365ms
mongodb
在常常按照文档的倒序查找的应用场景中,咱们能够经过创建索引来进行查找,以节约咱们的查找时间。数据库
db.collection.ensureIndex(keys, options)
复制代码
> db.classOne.ensureIndex({num: 1})
/* { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, // 添加本次索引以前的索引数 "numIndexesAfter" : 2, // 添加本次索引以后的索引数 "ok" : 1 } */
复制代码
> db.classOne.find({num: 1000000}).explain(true)
/* { "queryPlanner" : { ... "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", // 经过扫描索引进行查找 "keyPattern" : { "num" : 1 }, "indexName" : "num_1", // 若是没有指定索引名称的话, 默认格式为 ‘字段_1’ 或者 ‘字段_-1’ , 1 表明正序, -1 表明 倒序 "isMultiKey" : false, "multiKeyPaths" : { "num" : [ ] }, ... } }, ... }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 6, // 本次执行时间的毫秒数为 6ms !!! ... }, "serverInfo" : {...}, "ok" : 1 } */
复制代码
创建索引以前用时 365 ms
, 创建索引以后查找用时须要 6 ms
, 用时大大的减小了。数组
若是没有指定索引名称的话, 默认格式为 fieldName_1
或者 fieldName_-1
,若是想要自定义索引名称的话,能够在建立的时候指定名称,以下:缓存
> db.classOne.ensureIndex({name: 1}, {name:' myIndexName'})
/* { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } */
复制代码
> db.classOne.getIndexes()
/*
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_", // 原始的 根据 _id 字段 生成的索引
"ns" : "user.classOne"
},
{
"v" : 2,
"key" : {
"num" : 1
},
"name" : "num_1", // 根据 num 字段 升序 建立的索引
"ns" : "user.classOne"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : " myIndexName", // 本身命名建立的索引
"ns" : "user.classOne"
}
]
*/
复制代码
> db.classOne.find({num: "500000"}).hint({num:1}).explain(true)
复制代码
db.collectionName.dropIndex(IndexName) 删除指定的索引(IndexName)
db.collecitonName.dropIndex('*'); 删除全部索引
复制代码
db.collection.ensureIndex(keys, {background: true})
复制代码
mongodb能够自动对数组进行索引bash
> db.classOne.insert({hobby:['basketball','football','pingpang']});
> db.classOne.ensureIndex({hobby:1});
> db.classOne.find({hobby:'football'},{hobby:1,_id:0}).explain(true);
复制代码
查询的条件不止一个,须要用复合索引session
db.collection.ensureIndex({name:1,num:1});
复制代码
在必定的时间后会过时,过时后相应数据数据被删除,好比session、日志、缓存和临时文件数据结构
> db.classTwo.insert({time:new Date()});
> db.classTwo.ensureIndex({time:1},{expireAfterSeconds:10});
复制代码
note性能
大篇幅的文章中搜索关键词,MongoDB为咱们提供了全文索引网站
db.colleciton.ensureIndex({field: 'text'})
复制代码
note:
text
- 建立全文索引,1
- 升序索引,2
- 降序索引spa
$text
: 表示要在全文索引中查东西$search
: 后边跟查找的内容, 默认所有匹配// 原始数据
{ "_id" : ObjectId("5afa93eae82637e49ce12077"), "name" : "Lily", "content" : "I am a girl" }
{ "_id" : ObjectId("5afa93f6e82637e49ce12078"), "name" : "Tom", "content" : "I am a boy" }
{ "_id" : ObjectId("5afa9561e82637e49ce12079"), "name" : "Carl", "content" : "I do not know boy girl" }
复制代码
content
字段建立一个全文索引db.classThree.ensureIndex({content: 'text'})
复制代码
// 查找包含 ‘girl’ 的文档
> db.classThree.find({$text: {$search: 'girl'}})
// { "_id" : ObjectId("5afa93eae82637e49ce12077"), "name" : "Lily", "content" : "I am a girl" }
// 查找包含 ‘boy’ 的文档
> db.classThree.find({$text: {$search: 'boy'}})
// { "_id" : ObjectId("5afa93f6e82637e49ce12078"), "name" : "Tom", "content" : "I am a boy" }
// 查找包含 ‘girl’ 或者 ‘boy’ 的文档(屡次查找是 与 的关系)
> db.classThree.find({$text: {$search: 'boy girl'}})
/* { "_id" : ObjectId("5afa93eae82637e49ce12077"), "name" : "Lily", "content" : "I am a girl" } { "_id" : ObjectId("5afa9561e82637e49ce12079"), "name" : "Carl", "content" : "I do not know boy girl" } { "_id" : ObjectId("5afa93f6e82637e49ce12078"), "name" : "Tom", "content" : "I am a boy" } */
// 查找仅包含‘girl’ 不包含‘boy’的文档
> db.classThree.find({$text: {$search: 'girl -boy'}})
// { "_id" : ObjectId("5afa93eae82637e49ce12077"), "name" : "Lily", "content" : "I am a girl" }
// 就是要查找包含 ‘girl boy’ 字符的文档(须要转义)
> db.classThree.find({$text: {$search: '\"boy girl\"'}})
// { "_id" : ObjectId("5afa9561e82637e49ce12079"), "name" : "Carl", "content" : "I do not know boy girl" }
复制代码
屡次查找,多个关键字为或的关系,中间以空格隔开
支持转义符的,用\斜杠来转义
mongodb提供强大的空间索引能够查询出必定落地的地理坐标
2d
索引db.collection.ensureIndex({field:'2d'}, options)
复制代码
{ "_id" : ObjectId("5afaa078e82637e49ce1207a"), "gis" : [ 1, 1 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce1207b"), "gis" : [ 1, 2 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce1207c"), "gis" : [ 1, 3 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce1207d"), "gis" : [ 2, 1 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce1207e"), "gis" : [ 2, 2 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce1207f"), "gis" : [ 2, 3 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce12080"), "gis" : [ 3, 1 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce12081"), "gis" : [ 3, 2 ] }
{ "_id" : ObjectId("5afaa078e82637e49ce12082"), "gis" : [ 3, 3 ] }
复制代码
以下图:
> db.map.ensureIndex({gis:'2d'})
/* { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } */
复制代码
[1,1]
最近的四个点> db.map.find({gis:{$near: [1,1]}}).limit(4)
/* { "_id" : ObjectId("5afaa078e82637e49ce1207a"), "gis" : [ 1, 1 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207b"), "gis" : [ 1, 2 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207d"), "gis" : [ 2, 1 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207e"), "gis" : [ 2, 2 ] } */
复制代码
查询结果以下图:
[1,2]
和点[3,3]
为对角线的正方形中的全部的点> db.map.find({gis: {$within:{$box: [[1,2],[3,3]]}}})
/* { "_id" : ObjectId("5afaa078e82637e49ce1207b"), "gis" : [ 1, 2 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207e"), "gis" : [ 2, 2 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207c"), "gis" : [ 1, 3 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207f"), "gis" : [ 2, 3 ] } { "_id" : ObjectId("5afaa078e82637e49ce12081"), "gis" : [ 3, 2 ] } { "_id" : ObjectId("5afaa078e82637e49ce12082"), "gis" : [ 3, 3 ] } */
复制代码
查询结果以下图:
[2,2]
为圆心,以1
为半径为规则下圆心面积中的点> db.map.find({gis: {$within:{$center: [[2,2],1]}}})
/* { "_id" : ObjectId("5afaa078e82637e49ce1207b"), "gis" : [ 1, 2 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207d"), "gis" : [ 2, 1 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207e"), "gis" : [ 2, 2 ] } { "_id" : ObjectId("5afaa078e82637e49ce1207f"), "gis" : [ 2, 3 ] } { "_id" : ObjectId("5afaa078e82637e49ce12081"), "gis" : [ 3, 2 ] } */
复制代码
查询结果以下图:
note:
[1,1]
等角落里的坐标与[2,2]
的坐标距离是√2
1
为正序 -1
为倒序