没什么参考价值,一些零碎的东西的记录,涵盖了mongodb的基本使用

一、启动服务

./bin/mongod --dbpath $path --logpath $path --fork --port 27017
参数名参数描述
--dbpath数据存储目录
--logpath日志存储文件
--fork以后台进程运行
--port运行端口,默认27017
--smallfile占用更小空间启动

更多服务启动参数参照:

指定配置文件:

./mongod --config filepath

二、CRUD操作

1、数据库和collection的使用

隐式生成test

use test

插入数据,隐式生成collection

db.user.insert({"name":"ptbird"});

删除数据库

db.dropDatabase()

删除collection

db.user.drop()

2、插入文档 db.collectionName.insert({})

插入一条数据:(自动生成 _id 字段)

> db.user.insert({"name":"ptbird","age":20})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("5af92257daaa065fe480cfaf"), "name" : "ptbird", "age" : 20 }

插入多条数据:

> db.user.insert([{"name":"ptbird2","age":20},{"name":"ptbird3","age":21}])

> db.user.find()
{ "_id" : ObjectId("5af92257daaa065fe480cfaf"), "name" : "ptbird", "age" : 20 }
{ "_id" : ObjectId("5af922be53dd7f5bf6821405"), "name" : "ptbird2", "age" : 20 }
{ "_id" : ObjectId("5af922be53dd7f5bf6821406"), "name" : "ptbird3", "age" : 21 }

插入复杂的数据:
某些数据类型可能书字段下套json对象

> db.user.insert({"name":{firstname:"post","lastname":"bird"},skills:["javascript","php","html","css","nodejs"]});

> db.user.find()
{ "_id" : ObjectId("5af9240053dd7f5bf6821407"), "name" : { "firstname" : "post", "lastname" : "bird" }, "skills" : [ "javascript", "php", "html", "css", "nodejs" ] }

3、删除文档

语法:

db.collection.remove(     
    <query>,     
    {       
        justOne: <boolean>,
        writeConcern: <document> 
    } 
)
参数名参数描述
query删除条件,查询表达式
justOne是否只删除一个,默认false
writeConcern抛出异常的级别

如果不传输查询表达式,则会导致 collectionName 下所有数据被删除

> db.user.remove({name:"ptbird"})
WriteResult({ "nRemoved" : 1 })

4、查询文档 db.collection.find()db.collection.findOne()

> db.user.find({name:"ptbird2"})
{ "_id" : ObjectId("5af922be53dd7f5bf6821405"), "name" : "ptbird2", "age" : 20 }

查询某个属性列:

  • 1 表示查询,0 表示不查询 (默认 id 总是可以查出来)
> db.user.find({},{"name":1,_id:0})
{ "name" : "newptbird" }
{ "name" : "ptbird3" }
{ "name" : "postbird" }

按照年龄查询名字:

> db.user.find({age:{$gt:21}},{name:1,_id:0})
{ "name" : "newptbird" }
{ "name" : "postbird" }

5、更新文档 db.collection.update()

db.collection.update(    
    <query>, 
    <update>, 
    {       
        upsert: <boolean>,   
        multi: <boolean>,  
        writeConcern: <document>
    }
)
参数名参数描述
query查询表达式
update复制表达式 包括 $set,$unset,$inc,$rename
upsert如果不存在,则直接插入新数据,默认false
multi默认false,只更新一条记录,如果是true,则符合条件的都会更新
writeConcern抛出异常的级别
  • $set : 设置某个字段的数据
  • $unset : 移除某个字段
  • $rename:重命名某个字段
  • $inc:增长某个字段
  • $setOnInsert : 当upsert发生时,可以指定一些其他字段。
> db.user.update({"name":"ptbird"},{$set:{"name":"newptbird"},$inc:{age:2}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find().pretty()
{
    "_id" : ObjectId("5af922be53dd7f5bf6821405"),
    "name" : "newptbird",
    "age" : 22
}
{
    "_id" : ObjectId("5af922be53dd7f5bf6821406"),
    "name" : "ptbird3",
    "age" : 21
}

upsert 使用:

> db.user.update({name:"postbird"},{$setOnInsert:{age:23}},{upsert:true})
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("5af92f2f31f32f4a473e80ac")
})
> db.user.find().pretty();

{
    "_id" : ObjectId("5af92f2f31f32f4a473e80ac"),
    "name" : "postbird",
    "age" : 23
}

三、查询表达式:

1、比较查询操作符合逻辑查询操作符

表达式描述
$gt>
$gte>=
$inin
$lt<
$lte<=
$ne!=
$ninnot in
$and{$and:[{$lt:12},{$gt:6}]} 多个条件都为真则成立
$nor多个条件都不为真则成立
$oror
$notnot

等于

db.user.find({name:"ptbird"})

不等于

db.user.find({name:{$ne:"ptbird"}});

大于

db.user.find({age:{$gt:20}})

小于

db.user.find({age:{$lt:21}})

in 操作

取年龄是 20 和 22 的 name 列

db.user.find({age:{$in:[20,22]}})

and 操作

> db.user.find({$and:[{age:{$gt:20}},{age:{$lt:22}}]},{name:1,_id:0})
{ "name" : "ptbird3" }

2、元查询操作符

参数描述
$mod{age:{$mod:{5,0}} 对 age 模5,结果为0
$exists{age:{$exists:1}} 列存在
$type表示值的类型

3、数组查询操作符

参数描述
$all所有单元存在则匹配 {hobby:{$all:['a','b']}}

4、评估查询运算符

字段名描述
$regex正则匹配 {name:{$regex:/^ptbird/,$options:'i'}}

四、游标操作

声明游标:

const cursor = db.collection.find()

判断游标是否已经取到尽头:

cursor.hasNext()

取出游标的下一个单元:

cursor.next()

循环

在这个过程中,循环结束后,cursor 的游标就已经结束了,因此在循环 cursor 就没有了。

cursor.forEach((item)=>{
        print(item._id)
    });

游标在分页中的应用:

假设每页N行,当前是 page 页,就需要跳过前 (page-1)*N 行,mongodb 中通过 skip()limit() 方法来实现。

查询第30页,每页10条:

> let cursor = db.user.find().skip(29 * 10).limit(10)
> cursor.count()
1000

转换成数组:cursor.toArray()

转换成数组后,能够多次循环使用,写进内存中,但是大数据写进内存,可能会造成内存泄露。

let arrayRes  =  cursor.toArray();
arrayRes.forEach((item)=>{print(item.)})

五、索引

索引的命令参考链接:

1、索引的创建删除等操作

查看当前索引状态:

> db.collection.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.user"
    },
    {
        "v" : 2,
        "key" : {
            "sn" : 1
        },
        "name" : "sn_1",
        "ns" : "test.user"
    }
]

创建普通的单列索引:

// 1 正序  -1 降序
db.collection.createIndex({field:1/-1})

> db.user.createIndex({sn:1})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

删除索引:

_id 索引不允许删除

// 删除单个索引
db.collection.dropIndex({sn:1})
// 删除所有的索引
db.collection.dropIndexes()

创建多列索引:

// 1 正序  -1 降序
db.collection.createIndex({field1:1/-1,filed2:1/-1})

子文档查询:

一个子文档 collection 如下:

> db.shop.find({},{name:1,_id:0,spec:1}).pretty()
{ "name" : "nokia", "spec" : { "weight" : 100, "from" : "china" } }
{ "name" : "nokia", "spec" : { "weight" : 100, "from" : "england" } }

如:查询 spec 属性下的 area 属性值是 china 的数据:

> db.shop.find({'spec.from':'china'},{name:1,_id:0,spec:1}).pretty()
{ "name" : "nokia", "spec" : { "weight" : 100, "from" : "china" } }

子文档索引

使用上面的子文档

> db.shop.createIndex({'spec.area':1})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

2、索引的类别

包括 普通索引、唯一索引、稀疏索引、hash索引

唯一索引:

db.collection.createIndex({field:1/-1},{unique:true})

稀疏索引:

如果针对 field 建立索引,针对不含 field 列的文档,不会建立索引

而普通索引,会在不含 field 的列上建立索引,并且将该列视为 NULL

db.collection.createIndex({field:1/-1,{sparese:true}})

Hash索引:

db.collection.createIndex( { _id: "hashed" } )

3、重建索引

db.collection.reIndex()