MongoDB随笔

Mongodb

 

 

1. 安装mongodb

创建批处理bat文件:

  (指定mongodb的数据存储路径)

服务端启动:mongod --dbpath D:\w7系统\Java开发\mongodbdata

客户端启动:mongo 127.0.0.1:27017/admin(不加使用的是test用户)

数据格式都是bson格式:Bson是json的扩展

  1. 2.  Mongodb的简单命令大小写规范

创建数据库:use 库名  这是个临时数据库,什么都不干的话会被自动删除

给指定数据库添加集合并添加记录(文档):

Db.persons.insert({name:”user”}):db代表本数据库

Persons:在数据库中加入了一个persons集合

  Insert:插入一条记录   (Bson格式)

插入单条数据:

Insert语句:Db.集合名.insert({name:”user”})

Save语句:

批量插入:执行for循环

查询有哪些数据库():

Show dbs

查询数据库中有哪些集合(库里有哪些集合(表)):

Show collections

查询指定集合中的数据(文档:一行数据)

查询所有该集合中的数据:Db. 集合名.find();find():查询方法

查询第一条数据:db.集合名.findOne();

更新指定集合中的数据:就是修改

Db.集合名.update({key:”value”},{$set:{key:”新的值”}})   db.集合名.update({条件},{$set:{值}});

1.强硬式更新::就是新的文档替掉老的文档:一般不用

2.

批量更新:默认修改第一条数据:需要改后面的值为true

删除指定集合中的数据:remove()

删除集合中所有数据但不会删除索引::Db.集合名.remove();

根据条件删除:::Db.集合名.remove({key:”value”});{要删除的条件}。

删除集合(表):

Db. 集合名.drop();

删除数据库:

Db.dropDatabase();

查看数据库帮助和集合帮助:

Db.help();    db.集合名.help();

InsertOrUpdate操作:

当查询到相应的对象的时候是执行修改,没找到就找插入

3find()查询:查询器放在内部(就是花括号里面)

查询所要显示的字段

Db.集合名.find({查询条件},{字段名:1,字段名:1,……})查询条件为空代表所有,不需要就是0,需要是1,mongodb默认id查询出来

查询条件(条件符写在内部):查询出所有id小于3的name字段: Db.集合名.find({_id:{$lt:3}},{name:1,_id:0})

显示查询出_id小于3大于1的name字段: Db.集合名.find({_id:{$lt:3,$gt:1}},{name:1,_id:0}).

$lt==小于$lte==小于等于  $gt==大于  $gte==大于等于  $ne==不等于

$in==包含    $nin==不包含   ::{$in:[参数,参数1]}参数作用于数组

语法:db.集合名.find({_id:{$in:[1,3]}})::查询出_id包含数组内1或3的数据

查询出不包含_id为1或3的记录: db.集合名.find({_id:{$nin:[1,3]}})

Or查询:$or

查询出_id小于2或者age大于4的记录

语法:db.集合名.find({$or:[{_id:{$lt:2}},{age:{$gt:4}}]},{_id:1,age:1})

正则查询

Db.集合名.find({name:/2/i}):查询name中有2的记录

$not:取反查询:可以用到任何地方进行取反操作

Db.集合名.find({name:/2/i}):查询name中没有2的记录

数组查询:$allindex(角标)应用

Db.集合名.find({array:{$all:[“2”,”22”]}}):查询记录中的数组中含有2和22的记录

查询记录中的数组中第2个是44的记录:Db.集合名.find({“array.1”:”44”})

$size:查询指定长度的数组:不能与比较查询符一起使用

Db.集合名.find({“array”:{$size:5}}):查询出数组长度为5的记录

$slice:返回文档中指定数组的内部值

查询出_id为4中的数组中的第2个到第4个索引的值

语法:db.集合名.find({_id:4},{数组名:{$slice:[1,3]}})

查询出_id为4中的数组中最后一个索引的值

语法:db.集合名.find({_id:4},{数组名:{$slice:[1,3]}})

$count():查询总数

语法:db.collection.find().count()

Distinct:查询集合中某一个字段的所有值

Db.runCommand({distinct:”集合名”,key:”要查询的字段”}).values

Group:分组

按id分组 并且age大于2的记录

嵌套文档查询:(集合嵌套集合)

查出在a学校上过学的id

Db.集合名.find({school:{school:”a”}})。::查询的集合中的某条数据一定要全,不全查不出来

Db.集合名.find({“school.school”:”a”}})::这种格式不需要带集合中的某条记录的全部数据

$elemMatch 单条条件 组查询(例如某条记录上有某条记录上没有 就查询不出来。Mongodb默认能查出来)

 用于数组内查询

语法:db.集合名.find({数组名:{$elemMatch:{数组中key:”值”,数组中key:””}}})

查询再a学校上过学并scoal为e的记录

$where查询:用于复杂的查询,尽量少使用突然,特消耗性能,会影响性能

不是非常必要时,一定要避免使用”$where”查询,因为效率太低,相当的。文档在MongoDB中是以BSON格式保存的,在$where查询时,每个文档都要从BSON转换为javascript对象然后再通过”$where”中的表达式来运行。有时可以将常规查询作为前置过滤,再使用”$where”查询对结果进行调优

拿到集合中age大与3而且数组中的school为”a”的

语法:

db.person.find({$where:function(){

//得到查询结果的每一条文档的age

var age = this.age;

//得到文档中的school对象

var school = this.school;

//判断age是否大与3

if(age > 3){

//判断school是否为真

if(school){

//遍历

for(var j = 0;j<school.length;j++){

//判断

if(school[j].school == "a"){

//返回true

return true;

}                   

}

}

}

}})

limit查询返回指定的数据条数

Limit:分页查询

查询集合中前五条数据

Db.集合名.find().limit(5)

Skip查询:返回指定数据的跨度

查询出集合中的2-4条数据

Db.集合名.find().limit(2).skip(2)

Sort排序查询:

Db.集合名.find().sort({_id:-1}):::sort({key:value})::按照key排序,value为1时正序,为-1是倒序

查询集合中的所有数据,根据id倒序排序,

Sort排序的优先级:

Skip性能问题:

游标:

游标销毁条件:

使用快照的时候一定要用高级查询

高级查询:db.collection.find({$query:{_id:1}})::查询id为1 的记录

4.索引管理

数据量大的时候使用索引:查询性能提高,插入性能减弱,经常查询少插入的要用索引

创建索引:db.collection.ensureIndex({key:1})::key:要建索引的key,1是正序,-1倒序

创建索引同时指定索引的名字:db.collection.ensureIndex({key:1},{name:”名字”})

索引使用需要注意的地方:

唯一索引:可以解决插入重复的数值

Db.collection.ensureIndex({key:1},{unique:true})::unique:唯一索引

提出重复值:创建索引前不能有重复值:加上dropDupls:true;mongodb会自动删除重复值

hint():强制查询指定的索引

>:

name:索引key  1:正序或倒序(-1)

explain():详细查看本次查询使用的是哪个索引和查询数据的状态信息

查询数据库已经建立的索引

Db.system.indexes.find()

Db. system.namespace.find():加命名空间

后台执行:创建索引时会把表锁住

Db.collection.ensureIndex({key:1},{background:true})

 

删除索引:

精确删除索引

Db.runCommand({dropIndexes:”集合名”,index:”索引名”})

批量删除索引

Db.runCommand({dropIndexes:”集合名”,index:”*”})

2d索引:::$near:区间,范围。对地图进行查询

查询里(70,80)最近的3个点

语法:db.collection.find({gis:{$near:[开始,结束]}}).limit(3);

$box:盒子模型。$within

$center:圆形

$center:[[圆心],半径]

5.数据库命名规范:

6Mongodbshell内置JavaScript引擎可以直接执行js代码

定义一个插入数据的函数:   

调用这个函数:

7Update中的修改器

db.collection.update( criteria, objNew, upsert, multi )    四个参数的说明如下:

criteria: update的查询条件,类似sql update查询内where后面的

objNew: update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的

upsert: 这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。

multi: mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

update({'jobId':7888195,'loadFlag':{$gt:0}},{$set:{'loadFlag':NumberLong(0)}},false,true)

 

$set :指定一个键值对,存在就修改不存在就添加。语法:{$set:{key:value}}

$inc : 只是使用于数字类型,可以为指定的键相对应的值进行加减操作 语法:{$inc:{key:value}}。

$unset :删除指定的键。  语法:{$unset:{key:1}}

$push : 把value追加到key中去 key要是数据类型,如果key不存在会新增一个数组类型加进去。一次只能追加一个。如果追加多个的话就用$pushAll

$addToSet : 增加一个值到指定数组内,而且只有当这个值不在数组内才增加。语法:{$addToSet:{数组key:value}}

$pop :删除数组内的一个值,删除最后一个值{$pop:{key:1}},删除第一个值{$pop:{key:-1}}。

$pull :删除数组内指定的值。 语法:$pull:{数组key:value}

$pullAll :用法同pull,可以一次删除数组内多个指定的值 语法:

$ :数组定位器,如果数组中有多个数值我们执行对期中一部分进行操作。修改数组中指定位置的值

$addToSet$each结合完成批量数组更新 (批量判断式的导入数组数组(判断是否有该数据,没有就添加,有就不加))。语法db.text.update({_id:1},{$addToSet:{数组名:{$each:[“数据1”,”数据2”]}}})

8.函数

常用命令:::

runCommand函数和findAndModify函数

runCommand:可以执行mongodb中的特殊函数。命令执行器

findAndModify:特殊函数之一,用于返回更新或删除后的这条记录。如果修改的话一次只能操作一条数据。

语法:变量=db.runCommand({

“findAndModify”:”操作的集合名”,

“query”:”{key: value}”,:查询条件

“update”:{$set:{key:value}},:修改的数据

“new”:true   :控制返回修改之前的数据(false)还是修改之后的数据(true)})

9.固定集合

10.Gridfs:

Eval:脚本服务器

/*/*[name()='metadata']

/*/*[name()='metadata']

[org.dom4j.tree.DefaultElement@17b0b9 [Element: <metadata uri: http://www.openarchives.org/OAI/2.0/ attributes: []/>]]

11克隆collection

 

11、克隆collection

1)克隆远程colletion,使用cloneCollection命令完成将远程的collection复制到本地。

命令格式:db.runCommand({cloneCollection:”集合”,from:”原机器”,copyIndexes:false}),copyIndexes:是否复制索引

例子:132.42.33.175上test库t1表上有一条数据

> db.t1.find()

{ “_id” : ObjectId(“4fd9a4bf186cb1b6ac95907d”), “name” : “liangzhangping”, “addr” : “beijing” }

132.42.33.190上test库上t1表有两条条数据

> db.t1.find()

{ “_id” : ObjectId(“4fd9c517dcde2d0e33d08c76″), “name” : “liangzhangping”, “age” : 28 }

{ “_id” : ObjectId(“4fda1795a3d56c6a40f2bc26″), “name” : “liangzhangping”, “addr” : “jiangxi” }

现在将132.42.33.175上test库t1表的数据克隆到132.42.33.190上test库上t1表上,操作如下:

a、登录132.42.33.190机器上执行:

> db.runCommand({cloneCollection:”test.t1″,from:”132.42.33.175:28010″})

{ “ok” : 1 }

b、查看验证

> db.t1.find()

{ “_id” : ObjectId(“4fd9c517dcde2d0e33d08c76″), “name” : “liangzhangping”, “age” : 28 }

{ “_id” : ObjectId(“4fda1795a3d56c6a40f2bc26″), “name” : “liangzhangping”, “addr” : “jiangxi” }

{ “_id” : ObjectId(“4fd9a4bf186cb1b6ac95907d”), “name” : “liangzhangping”, “addr” : “beijing” }

2)克隆本地collection,MongoDB没有提供命令进行本地复制,但我们可以写一个循环插入的方法完成,

例如:将source_collection中的数据复制一份到target_collection,代码如下:

db.source_collection.find().forEach(function(x){db.target_collection.insert(x)})

2、复制数据库,使用copyDatabase命令完成复制数据库,

格式:copyDatabase(fromdb,todb,fromhost[,username,password])

fromdb:源数据库名称

todb:目标数据库名称

fromhost:源数据库地址,本地和远程都可以

username:远程数据库用户名

password:远程数据密码

例子:将本地db2库复制本地,并重命名db1

> db.copyDatabase(“db2″,”db1″,”localhost”)

3、刷新磁盘:将内存中尚未写入磁盘的信息写入磁盘,并锁住对数据库更新的操作,但读操作可以使用,使用runCommand命令,这个命令只能在admin库上执行

格式:db.runCommand({fsync:1,async:true})

async:是否异步执行

lock:1 锁定数据库

4、数据压缩:mongodb的存储结构采用了预分配的机制,长期不断的操作,会留下太多的的碎片,从而导致数据库系统越来越慢。

repairDatabase命令是mongodb内置的一个方法,它会扫描数据库中的所有数据,并将通过导入/导出来重新整理数据集合,将碎片清理干净

现在看压缩前和压缩后的对比数据,如下所示:

PRIMARY> db.t1.storageSize()

65232896

PRIMARY> db.t1.totalSize()

81470432

PRIMARY> db.repairDatabase()

{ “ok” : 1 }

PRIMARY> db.t1.storageSize()

65232896

PRIMARY> db.t1.totalSize()

79851584

相同主机上 不同库的collection集合拷贝

db.SOURCE_M01.find().forEach(function(d){ db.getSiblingDB('nstlStorage_2')['SOURCE_M01'].insert(d); });

导出

./mongoexport -h 127.0.0.1 -d nstlStorage -c SOURCE_Q01 -o /data5T/Q01

./mongoimport -h 127.0.0.1 -d nstlStorage-4 -c SOURCE_E01 /data/mongodb/data_bak/E01 -drop

12权限认证

mongodb 启动参数 加上 --auth  才开启验证

1,mongodb是没有默认管理员账号,所以要先添加管理员账号,在开启权限认证。

2,切换到admin数据库,添加的账号才是管理员账号。

3,用户只能在用户所在数据库登录,包括管理员账号。

4,管理员可以管理所有数据库,但是不能直接管理其他数据库,要先在admin数据库认证后才可以

5.创建用户:

db.createUser(user:“用户名”,pwd:”密码”,roles :[{role:””,db:”数据库名”}])

user文档字段介绍:

           user字段,为新用户的名字;

            pwd字段,用户的密码;

             cusomData字段,为任意内容,例如可以为用户全名介绍;

            roles字段,指定用户的角色,可以用一个空数组给新用户设定空角色;

            roles字段,可以指定内置角色和用户定义的角色。

 Built-In Roles(内置角色):

    1. 数据库用户角色:read、readWrite;

    2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;

    3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;

    4. 备份恢复角色:backup、restore;

    5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

    6. 超级用户角色:root  

    // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)

    7. 内部角色:__system

    PS:关于每个角色所拥有的操作权限可以点击上面的内置角色链接查看详情。

例如:在products数据库创建用户accountAdmin01,并给该用户admin数据库上clusterAdmin和readAnyDatabase的角色,products数据库上readWrite角色。

use products

db.createUser( { "user" : "accountAdmin01",

                 "pwd": "cleartext password",

                 "customData" : { employeeId: 12345 },

                 "roles" : [ { role: "clusterAdmin", db: "admin" },

                             { role: "readAnyDatabase", db: "admin" },

                             "readWrite"

                             ] },

               { w: "majority" , wtimeout: 5000 } )

13修改mongodb中的oplog的大小

停掉mong进程 并修改端口 以单机形式重启  主节点要改备份节点

 1、备份oplog

 ./mongodump --db local --collection 'oplog.rs' --host 127.0.0.1  --port 37017

 2、进入数据库

  ./mongo 127.0.0.1:37017

 3、进入local库

  use local

4、把oplog日志最后一条记录保存在临时表

 db.temp.save(db.oplog.rs.find({},{ts:1,h:1}).sort({$natural:-1}).limit(1).next())

 5、删除掉旧的oplog.rs表

  db.oplog.rs.drop()

 6、创建新的oplog表   300M

 db.runCommand({create:'oplog.rs',capped:true,size:(300*1024*1024)})

 7、在新的oplog表中插入保存临时表的数据

 db.oplog.rs.save(db.temp.findOne())

 最后关掉进程 修改配置文件为集群模式 重新启动

 

14mongodb创建副本集

三台服务器安装mongodb后

选其中一台执行

cd mongodb/bin/

./mong 127.0.0.1:27017

use admin

cfg={"_id":"storage","members":[{“_id”:0,”host”:'127.0.0.1:27017},{“_id”:1,”host”:'127.0.0.1:27017},{“_id”:2,”host”:'127.0.0.1:27017}]};

rs.initiate(cfg)//初始化

 

 //注释

"_id":"storage":::副本集名称

members :副本集成员

 

Mongodb集成spring

Spring中的设置ReadPreference

1

<!-- mongodb配置 -->

<mongo:mongo id="mongo"  host="${mongo.host}" port="${mongo.port}" write-concern="NORMAL" >

    <mongo:options 

        connections-per-host="${mongo.connectionsPerHost}"

        threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"

        connect-timeout="${mongo.connectTimeout}" 

        max-wait-time="${mongo.maxWaitTime}"

        auto-connect-retry="${mongo.autoConnectRetry}" 

        socket-keep-alive="${mongo.socketKeepAlive}"

        socket-timeout="${mongo.socketTimeout}" 

        slave-ok="${mongo.slaveOk}"

        write-number="1" 

        write-timeout="0" 

        write-fsync="false"

    />

</mongo:mongo>

<!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->

<mongo:db-factory id="mongoDbFactory" dbname="uba" mongo-ref="mongo" />

<!-- 读写分离级别配置  -->

<!-- 首选主节点,大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。 -->

<bean id="primaryPreferredReadPreference" class="com.mongodb.TaggableReadPreference.PrimaryPreferredReadPreference" />

<!-- 最邻近节点,读操作在最邻近的成员,可能是主节点或者从节点。  -->

<bean id="nearestReadPreference" class="com.mongodb.TaggableReadPreference.NearestReadPreference" />

<!-- 从节点,读操作只在从节点, 如果从节点不可用,报错或者抛出异常。存在的问题是secondary节点的数据会比primary节点数据旧。  -->

<bean id="secondaryReadPreference" class="com.mongodb.TaggableReadPreference.SecondaryReadPreference" />

<!-- 优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据  -->

<bean id="secondaryPreferredReadPreference" class="com.mongodb.TaggableReadPreference.SecondaryPreferredReadPreference" />

<!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 -->

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">

    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />

    <property name="readPreference" ref="primaryPreferredReadPreference" />

</bean>

15.

.

原文地址:https://www.cnblogs.com/xiaoxiaoshuai/p/9178694.html