文章19 | 阅读 9929 | 点赞0
要想能熟练操作MongoDB,首先先要熟练使用 MongoDB Shell, 再次要熟练使用驱动 mongodb-java-driver, 最后是spring-data-mongodb的使用
MongoDB 简介:
MongoDB采用Bson格式存储,BSON格式比JSON数据类型更加丰富,
支持ObjectId、日期类型、正则表达式、JS代码、二进制数据等
MongoDB注意:
以 $ 开头,如
$set(更新字段)、
$unset(删除字段)、
$inc(自增或自减)、
$and、$or、$in、$nin、$nor、$exists(用于判断文档中是否包含某字段)、
$push(向数组中尾部添加一个元素)、
$pushAll(将数组中的所有值push)、
$addToSet(向set集合中添加元素)、
$pop(删除数组中的头部或尾部元素),
$pull(删除数组中指定的值)、
$size(根据数组的长度进行筛选)、
$slice(返回数组中部分元素,如前几个、后几个、中间连续几个元素)、
$elemMatch(用于匹配数组中的多个条件)、
$where(自定义筛选条件,效率比较低,需要将bson转为js对象,不能使用索引,可以先使用普通查询过滤掉部分不满足条件的文档,然后再使用where,尽量减少where操作文档的数量过大)
MongoDB 与 关系型数据库的对比:
MongoDB的数据时存储在磁盘上的,而不是存储在内存中的,所以在启动MongoDB服务时需要指定数据存储的位置, 如果不指定会默认存储在/data/db目录下, 注意在使用默认位置时,需要以管理员身份预先创建好目录
C:\Windows\system32>D:
D:\>mkdir data
D:\>cd data
D:\data>mkdir db
D:\data>cd D:\Java\MongoDB\Server\bin
D:\Java\MongoDB\Server\bin>mongod
MongoDB starting : pid=9712 port=27017 dbpath=D:\data\db\ 64-bit host=zm-PC
此种方式也要预先创建好目录,这里的位置放置MongoDB里面,如D:\Java\MongoDB\DB,放在MongoDB里面不需要管理员身份创建
D:\Java\MongoDB\Server\bin>mongod --dbpath=D:\data\db --logappend --logpath=D:\data\log.txt --install
以后启动服务只需要net start MongoDB, 比mongod --dbpath=xxx
稍微方便些, 以后电脑开机后就自动启动了,省的每次都要启动
语法: mongo [IP:PORT][/DATABASE_NAME]
IP默认的是127.0.0.1
Port默认的是27017
database默认的是test,mongodb中默认有两个数据库admin、local
D:\Java\MongoDB\Server\bin>mongo
D:\Java\MongoDB\Server\bin>mongo 127.0.0.1:27017
D:\Java\MongoDB\Server\bin>mongo 127.0.0.1:27017/admin
// 连接时不指定要连接数据库,需要时从连接中获取需要的数据库
D:\Java\MongoDB\Server\bin>mongo --nodb
MongoDB shell version v3.4.6
> db
2017-07-27T20:27:25.181+0800 E QUERY [thread1] ReferenceError: db is not defined :
@(shell):1:1
> conn = new Mongo("localhost:27017")
connection to localhost:27017
> db = conn.getDB("test")
test
>
help命令:如果想知道某个对象下都有哪些函数可以使用help命令,直接使用help会列举出mongodb支持操作,使用db.help()会列举所有db对象所支持的所有操作,使用db.mycoll.help()可以列举所有集合对象对应的操作
> help
db.help() help on db methods
db.mycoll.help() help on collection methods
sh.help() sharding helpers
rs.help() replica set helpers
help admin administrative help
help connect connecting to a db help
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, 'global' is default
use <db_name> set current database
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
// 查看所有数据级别的操作
> db.help()
// 查看集合级别的操作
> db.mycoll.help()
// 列举数据库命令
> db.listCommands()
查看函数方法的实现或者查看方法的定义(比如忘记函数的参数了)可以通过输入函数名,不带小括号
> db.foo.update
function (query, obj, upsert, multi) {
var parsed = this._parseUpdate(query, obj, upsert, multi);
...
}
// 打印语句
> print("hello, mongodb")
hello, mongodb
>
// 执行js脚本
D:\Java\MongoDB\Server\bin>mongo script1.js script2.js
loading file: script1.js
I am script1.js
loading file: script2.js
I am script2.js
// 使用load()函数加载脚本来执行
> load("script1.js")
I am script1.js
true
// script3.js
print(db.getMongo().getDBs()); // show dbs
db.getSisterDB("foo"); // use foo
db.users.insert({"username": "mengday", "age": 26})
print(db.getCollectionNames()); // show collections
> load("script3.js")
[object BSON]
users
true
>
// 使用脚本可以定义一些辅助的工具函数
tools.js
var connectTo = function (port, dbname) {
if(!port) port = 27017;
if(!dbname) dbname = "test";
db = connect("localhost:" + port + "/" + dbname);
return db;
}
> load("tools.js")
true
> typeof connectTo
function
> connectTo("27017", "admin")
connecting to: mongodb://localhost:27017/admin
MongoDB server version: 3.4.6
admin
>
客户端启动时自动执行js脚本
在用户的主目录下(如C:\Users\mengday)下创建一个.mongorc.js文件,该脚本可以做一些操作,如重写shell命令,禁掉一部分功能,如删除数据库,表等危险操作
// .mongorc.js
print("--------------MongoDB is started--------------");
var no = function(){
print("not permission");
}
db.dropDatabase = DB.prototype.dropDatabase = no;
DBCollection.prototype = no;
DBCollection.prototype.dropIndex = no;
// 启动shell时会自动执行
D:\Java\MongoDB\Server\bin>mongo
MongoDB shell version v3.4.6
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.6
----------------MongoDB is started-----------------
> db
test
> db.dropDatabase()
not permission
>
// mongo 启动后给EDITOR变量赋值一个文本编辑器的位置,然后就可以使用edit命令来打开编辑某个变量了,编辑后保存,然后直接关掉编辑器即可,这对于一条命令或者变量比较长编辑比较方便,注意文本编辑器的位置不能包含空格,路径要使用/,不能使用\
EDITOR="D:/SublimeText/sublime_text.exe"
var user = {"username": "mengday", "nickname": "xxx"};
edit user
// 方式二:可以将该配置放在.mongorc.js中,以后就不用每次设置了
EDITOR="D:/SublimeText/sublime_text.exe";
查看当前数据库 db
显示所有数据库 show dbs,如果数据库里没有任何集合,是不展示出来的,如 use test2, show dbs 时是不包含test2数据库的
切换或者新建数据库 use DATABASE_NAME, 切换数据库时如果数据库不存在,则会创建它
删除数据库 db.dropDatabase()
显示所有表(集合)show tables
查看js方法的原型(源代码实现): db.xxx.insert, 随便写一个集合名字,集合后面跟函数名,不需要函数的参数 即可查看该函数的源码实现
// mong shell 是一种javascript shell, 可以定义变量、函数,调用函数
> x = 200
200
> x / 5
40
> Math.sin(Math.PI / 2)
1
// new Date():是创建一个日期对象,而Date()函数是返回日期字符串,注意日期类型数据和字符串数据不是一种数据,MongoDB Shell在操作日期字段的时候是操作的日期类型而不是字符串类型
> new Date()
ISODate("2017-07-27T00:18:34.370Z")
> Date()
Thu Jul 27 2017 08:18:37 GMT+0800
>
> "Hello, World!".replace("World", "MongoDB")
Hello, MongoDB!
> function factorial(n) {
... if(n <= 1) return 1;
... return n * factorial(n - 1);
... }
> factorial(5)
120
>
// db 是一个全局变量,存储当前的数据名称,当切换数据库时会自动更改db的值
> db
test
> show dbs
admin 0.000GB
local 0.000GB
> use local
switched to db local
> show tables
startup_log
> use test
switched to db test
> db.dropDatabase()
{ "ok" : 1 }
> db.xxx.insert
// 查看一个bson的大小,每个文档最大不超过16M
> var user = {"username": "mengday"}
> Object.bsonsize(user)
27
方式一:隐式创建集合
当向集合中的插入文档时,如果集合不存在,系统会自动创建,所以向一个不存在的集合中插入数据也就是创建了集合
> db
test
> show tables
> db.users.insert({"usernmae": "mengdee", "age": 26})
WriteResult({ "nInserted" : 1 })
> show tables
users
>
方式二:显示创建集合
db.createCollection(“集合名字”, 可选配置)
显示创建集合可以通过一些配置创建一些特殊的集合,如固定集合
> show tables
users
> db.createCollection("address")
{ "ok" : 1 }
// 固定集合只能通过调用方法显式创建,固定集合可以指定集合存储数据的大小和最多允许存储的条数
// 当固定集合文档条数达到上限时,再插入新的文档会将最老的文档删除掉,然后插入到该位置
> db.createCollection("address", {capped: true, size: 10000, max:1000})
{ "ok" : 1 }
> show tables
address
users
>
db.集合名字.drop()
> db.address.drop()
true
show tables和show collections都可以查看当前数据下的集合
> show tables
address
users
>
> show collections
address
users
>
方式一: insert: _id 会自动创建唯一索引,当id重复的时候会报错
db.集合名字.insert({}) // 插入一条,返回值中不包含insertedIds
db.集合名字.insert([{}, {}]) // 批量插入,返回值中不包含insertedIds
db.集合名字.insertOne(Bson) // 插入一条,返回值返回插入的insertedId
db.集合名字.insertMany(Bson) // 批量插入,返回值中包含insertedIds
db.集合名字.findAndModify({查询条件}, "update": {需要添加或更新的字段}, "upsert": true });
写入安全:
应答模式:插入时会返回成功或者失败
非应答模式:插入时没有反馈,即插入有没有成功不知道
> var user = {"name": "mengdee", "age": 20, "address": "上海市浦东新区张江镇", "create_time": new Da
te()}
> db.users.insert(user)
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("5976ad21670af2aa52ea90df"), "username" : "mengdee", "age" : 26 }
{ "_id" : ObjectId("5976b395670af2aa52ea90e0"), "name" : "mengdee", "age" : 20, "address" : "上海市
浦东新区张江镇", "create_time" : ISODate("2017-07-25T02:57:04.545Z") }
> var userDoc = db.users.findOne()
> var insertDate = userDoc["_id"]
> insertDate.getTimestamp()
ISODate("2017-07-25T02:29:53Z")
> insertDate.str
5976ad21670af2aa52ea90df
> db.users.insertOne({"username": "mengday3"})
{
"acknowledged" : true,
"insertedId" : ObjectId("5976b632670af2aa52ea90e1")
}
> db.users.insertMany([{"username": "mengday4"}, {"username": "mengday5"}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5976b666670af2aa52ea90e2"),
ObjectId("5976b666670af2aa52ea90e3")
]
}
> db.users.insert([{"username": "mengday6"}, {"username": "mengday7"}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
// 使用insertOne插入重复的_id 会报错
> db.users.insertOne({"_id": 1, "username": "mengday8"})
{ "acknowledged" : true, "insertedId" : 1 }
> db.users.insertOne({"_id": 1, "username": "mengday8"})
2017-07-25T11:15:47.822+0800 E QUERY [thread1] WriteError: E11000 duplicate key error collection:
test.users index: _id_ dup key: { : 1.0 } :
WriteError({
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.users index: _id_ dup key: { : 1.0 }
",
"op" : {
"_id" : 1,
"username" : "mengday8"
}
})
// findAndModify 也可以用于插入文档,但是前提是一定不存在,如果存在了就变成更新了,单纯的插入还是不要用种方式了,findAndModify一般用于更新或删除操作
> db.users.findAndModify({ "query": {"username": "mengday11"}, "update": {"username": "mengday11", "age": 26}, "upsert": true })
null
> db.users.find()
{ "_id" : ObjectId("597c584448c373e228a9259e"), "username" : "xxx", "age" : 26 }
MongoDB Shell是一种JS,所以可以通过var来定义变量,可以通过find()方法来查找集合中的所有数据,相当于select * from users
插入数据时,如果没有指定_id这个字段,系统会自动生成一个值,从该值中能够解析出插入文档的日期或者获取日期中的字符串值
方式二:save()
db.集合名字.save(Bson) : 如果要插入的文档没有指定_id,则插入文档,如果指定_id,如果集合中不包含_id,则插入文档,如果集合中已经存在相同的id值,则更会整体替换
> db.users.find()
{ "_id" : 1, "username" : "mengday8" }
{ "_id" : 2, "username" : "mengday8" }
> db.users.save({ "_id" : 3, "mengday9" : 20})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 3 })
> db.users.save({ "_id" : 2, "age" : 20, "gender": 1 })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday8" }
{ "_id" : 2, "age" : 20, "gender" : 1 }
{ "_id" : 3, "mengday9" : 20 }
>
> db.users.save([{ "_id" : 4, "username": "mengday9"}, { "_id" : 5, "username":"mengday10"}])
方式三: update()
update({查询条件}, {更新的文档}, 是否开启addOrUpdate) : addOrUpdate为true,当集合中不存在的时候就插入,存在就更新
> db.users.find()
{ "_id" : 5, "username" : "mengday10" }
> db.users.update({"username" : "mengday11"}, { "_id" : 6, "age" : 20, "gender" : 1 }, true)
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 6 })
> db.users.find()
{ "_id" : 5, "username" : "mengday10" }
{ "_id" : 6, "age" : 20, "gender" : 1 }
>
remove({删除条件}): 删除满足条件的所有数据
remove({删除条件}, true): 删除满足条件的第一条数据
remove({}): 清空集合中的所有文档
// 删除bson变量中的某个字段
> var user = {"username": "mengday", "age": 26}
> delete user.age
> user
{ "username" : "mengday" }
> db.users.find()
{ "_id" : 1, "username" : "mengday", "password" : "123456" }
{ "_id" : 2, "username" : "mengday2", "password" : "123456" }
{ "_id" : 3, "username" : "mengday3", "password" : "123456", "age" : 18 }
{ "_id" : 4, "username" : "mengday4", "password" : "123456", "age" : 28 }
{ "_id" : 5, "username" : "mengday5", "password" : "123456", "age" : 38 }
> db.users.remove({age: {$lt: 38}})
WriteResult({ "nRemoved" : 2 })
> db.users.find()
{ "_id" : 1, "username" : "mengday", "password" : "123456" }
{ "_id" : 2, "username" : "mengday2", "password" : "123456" }
{ "_id" : 5, "username" : "mengday5", "password" : "123456", "age" : 38 }
> db.users.remove({"password": "123456"}, true)
WriteResult({ "nRemoved" : 1 })
> db.users.find()
{ "_id" : 2, "username" : "mengday2", "password" : "123456" }
{ "_id" : 5, "username" : "mengday5", "password" : "123456", "age" : 38 }
> db.users.remove({})
WriteResult({ "nRemoved" : 2 })
// findAndModify可以用来插入或更新upsert、也可以用来删除
> db.users.findAndModify({
"query": {"username": "mengday"},
"remove": true
})
{
"_id" : ObjectId("597c3c1587d089dfa7ce1be3"),
"username" : "mengday",
"addresses" : [
{
"city" : "shanghai",
"area" : "zhangjiang"
},
{
"city" : "beijing",
"area" : "CHAOYANG"
}
],
"create_time" : ISODate("2017-07-29T09:09:14.031Z")
}
更新指定字段的值
替换整个文档
更新满足条件的第一条文档
更新满足条件的所有文档
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "age" : 38 }
// 使用$set修改器修改指定字段, 当字段不存在时会创建并赋值
> db.users.update({"username": "mengday5"}, {$set: {"age": 18}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "age" : 18 }
// $unset 用于删除字段
> db.users.update({"username": "mengday5"}, {"$unset": {"age": 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456" }
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456" }
// $push: 向数组的尾部添加一个元素,如果字段不存在则创建
> db.users.update({"username": "mengday5"}, {"$push": {"hobby": "mm"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "mm" ] }
> db.users.update({"username": "mengday5"}, {"$push": {"hobby": "money"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "mm", "money" ] }
>
// $push + $each : 批量push
> db.users.update({"username": "mengday5"}, {"$push": {"hobby": {"$each": ["play", "eat"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "mm", "money", "play", "eat" ] }
>
// $pushAll = $push + $each 批量push
> db.users.update({"username": "mengday5"}, {"$pushAll": {"hobby": ["drink", "happy"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "mm", "money", "play", "eat", "drink", "happy" ] }
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456" }
// $addToSet:不重复的set集合
> db.users.update({}, {"$addToSet": {"hobby": "eat"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "eat" ] }
>
> db.users.update({}, {"$addToSet": {"hobby": {"$each": ["eat", "drink"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "eat", "drink" ] }
>
// $pop: 弹出数组的头部元素或尾部元素: -1:头部,1:尾部
> db.users.update({}, {"$pop": {"hobby": 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday5", "password" : "123456", "hobby" : [ "eat" ] }
// $pull: 删除数组中的值
> db.lists.insert({"no": [1, 1, 1, 3]})
WriteResult({ "nInserted" : 1 })
> db.lists.update({}, {"$pull": {"no": 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.lists.find()
{ "_id" : ObjectId("597c0a3087d089dfa7ce1be2"), "no" : [ 3 ] }
>
// 使用小标或者定位操作符$来操作数组
> db.users.find()
{ "_id" : ObjectId("597c3c1587d089dfa7ce1be3"), "username" : "mengday", "addresses" : [ { "city" : "shanghai", "area" : "zhangjiang" }, { "city" : "be
ijing", "area" : "chaoyang" } ] }
>
// 修改内嵌文档数组中第二个元素的值
> db.users.update({"username": "mengday"}, {"$set": {"addresses.1.area": "chaoyangqu"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
"_id" : ObjectId("597c3c1587d089dfa7ce1be3"),
"username" : "mengday",
"addresses" : [
{
"city" : "shanghai",
"area" : "zhangjiang"
},
{
"city" : "beijing",
"area" : "chaoyangqu"
}
]
}
// 定位操作符$: 查询条件一般是以数组中的元素为条件,使用$符号作为满足查询条件的第一条文档对应的下标值
> db.users.update({"addresses.city": "beijing"}, {"$set": {"addresses.$.area": "CHAOYANG"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
"_id" : ObjectId("597c3c1587d089dfa7ce1be3"),
"username" : "mengday",
"addresses" : [
{
"city" : "shanghai",
"area" : "zhangjiang"
},
{
"city" : "beijing",
"area" : "CHAOYANG"
}
]
}
// 文档整体替换
> db.users.update({"username": "mengday5"}, {"age": 17})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "age" : 17 }
// 第三个参数: 插入或者更新,当_id不存在的时候插入,当_id值存在的时候更新
> db.users.update({"_id": 2}, {"username": "mengday", "age": 16}, true)
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 2 })
> db.users.find()
{ "_id" : 1, "age" : 17 }
{ "_id" : 2, "username" : "mengday", "age" : 16 }
// 更新
> db.users.update({"_id": 2}, {"username": "mengday2", "birthday": new Date()}, true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "age" : 17 }
{ "_id" : 2, "username" : "mengday2", "birthday" : ISODate("2017-07-25T06:33:10.579Z") }
> db.users.find()
{ "_id" : 1, "username" : "mengday", "age" : 16 }
{ "_id" : 2, "username" : "mengday2", "age" : 16 }
// 更新满足条件的第一条文档
> db.users.update({"age": 16}, {$set: {"age": 18}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : 1, "username" : "mengday", "age" : 18 }
{ "_id" : 2, "username" : "mengday2", "age" : 16 }
// 第三个参数:insertOrUpdate, 第四个参数:是否批量更新,true就是更新所有满足条件的文档
> db.users.update({"age": {$gte: 16}}, {$set: {"age": 25}}, false, true)
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
> db.users.find()
{ "_id" : 1, "username" : "mengday", "age" : 25 }
{ "_id" : 2, "username" : "mengday2", "age" : 25 }
>
// 查询然后更新,更新是整体替换, 如果想更新指定的字段使用$set修改器即可
> db.users.findAndModify({
query: { "username": "mengday"},
update:{
"age": 20,
"username": "mengday20"
}
})
{
"_id" : 1,
"username" : "mengday",
"age" : 20,
"birthday" : ISODate("2017-07-25T07:05:28.286Z")
}
> db.users.find()
{ "_id" : 1, "age" : 20, "username" : "mengday20" }
// 查询所有, 相当于 select * from users
> db.users.find()
{ "_id" : 1, "username" : "mengday", "age" : 20, "birthday" : ISODate("2017-07-25T07:05:28.286Z") }
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
{ "_id" : 3, "username" : "xiaohong", "age" : 28, "birthday" : ISODate("2017-07-25T07:06:13.741Z") }
{ "_id" : 4, "username" : "xiaoming", "age" : 27, "birthday" : ISODate("2017-07-25T07:06:44.812Z") }
{ "_id" : 5, "username" : "sunday", "age" : 37, "birthday" : ISODate("2017-07-25T07:07:45.420Z") }
>
// pretty() 用于格式化查询的结果
> db.users.find().pretty()
{
"_id" : 1,
"username" : "mengday",
"age" : 20,
"birthday" : ISODate("2017-07-25T07:05:28.286Z")
}
...
{
"_id" : 5,
"username" : "sunday",
"age" : 37,
"birthday" : ISODate("2017-07-25T07:07:45.420Z")
}
>
// 查询一条, 相当于select * from users limit 1
> db.users.findOne()
{
"_id" : 1,
"username" : "mengday",
"age" : 20,
"birthday" : ISODate("2017-07-25T07:05:28.286Z")
}
// 查询条件, 相当于 select * from users where age < 20
> db.users.find({"age": {$lt: 20}})
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
// 查询指定的字段,1:代表要查询的字段,0:代表不要查询的字段 ,相当于 select username, age from users where age < 20
> db.users.find({"age": {$lt: 20}}, {"_id":0, "username": 1, "age": 1})
{ "username" : "tom", "age" : 18 }
// and 条件,多个调剂直接用逗号分开,不需要什么操作符: 相当于 select * from users where age < 20 and id < 3
> db.users.find({"age": {$lt: 30}, "_id": {$lt: 3 }})
{ "_id" : 1, "username" : "mengday", "age" : 20, "birthday" : ISODate("2017-07-25T07:05:28.286Z") }
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
// 同一个字段多个条件: 相当于 select * from users where age > 25 and age < 30
> db.users.find({"age": {$gt: 25, $lt:30 }})
{ "_id" : 3, "username" : "xiaohong", "age" : 28, "birthday" : ISODate("2017-07-25T07:06:13.741Z") }
{ "_id" : 4, "username" : "xiaoming", "age" : 27, "birthday" : ISODate("2017-07-25T07:06:44.812Z") }
// or: 相当于 select * from users where age > 30 or username = 'tom'
> db.users.find({$or: [{"age": {$gt: 30}}, {"username": "tom"}]})
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
{ "_id" : 5, "username" : "sunday", "age" : 37, "birthday" : ISODate("2017-07-25T07:07:45.420Z") }
// and or 混合使用,相当于 select * from users where id < 4 and (username = 'mengdat' or age < 20)
> db.users.find({ $or: [{"username": "mengday"}, {"age": {$lt: 20}}], "_id": {$lt: 4} })
{ "_id" : 1, "username" : "mengday", "age" : 20, "birthday" : ISODate("2017-07-25T07:05:28.286Z") }
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
>
// in: 相当于 select * from users where age in (18, 28)
> db.users.find({"age": {$in: [18, 28]}})
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
{ "_id" : 3, "username" : "xiaohong", "age" : 28, "birthday" : ISODate("2017-07-25T07:06:13.741Z") }
>
// 正则表达式不但可以匹配字符串还可以匹配字段值是正则表达式类型的,此时是相等匹配
// 模糊查询,正则表达式: 以xiao开头,以ng结尾
// 相当于 select * from users where username like 'xiao%' and username like '%ng'
> db.users.find({"username": /^xiao/, "username": /ng$/})
{ "_id" : 3, "username" : "xiaohong", "age" : 28, "birthday" : ISODate("2017-07-25T07:06:13.741Z") }
{ "_id" : 4, "username" : "xiaoming", "age" : 27, "birthday" : ISODate("2017-07-25T07:06:44.812Z") }
> db.users.insert({"_id": 6, "username": "sunday", "age": 39, "birthday": new Date(), "hobby": ["eat
", "drink", "play", "happy", "money", "mm"] })
WriteResult({ "nInserted" : 1 })
// 正则表达式忽略大小写
> db.users.find({"username": {$regex:/sunday/, $options:"$i"}})
{ "_id" : 5, "username" : "sunday", "age" : 37, "birthday" : ISODate("2017-07-25T07:07:45.420Z") }
{ "_id" : 6, "username" : "SunDay", "age" : 39, "birthday" : ISODate("2017-07-25T07:53:16.072Z"), "h
obby" : [ "eat", "drink", "play", "happy", "money", "mm" ] }
// 正则表达式用于数组
> db.users.find({"hobby": {$regex: "mm"}})
{ "_id" : 6, "username" : "SunDay", "age" : 39, "birthday" : ISODate("2017-07-25T07:53:16.072Z"), "h
obby" : [ "eat", "drink", "play", "happy", "money", "mm" ] }
// 正则表达式包含变量时需要使用eval()函数来计算
> var username = "sunday"
> db.users.find({"username": {$regex:eval("/" + username + "/i")}})
{ "_id" : 5, "username" : "sunday", "age" : 37, "birthday" : ISODate("2017-07-25T07:07:45.420Z") }
{ "_id" : 6, "username" : "SunDay", "age" : 39, "birthday" : ISODate("2017-07-25T07:53:16.072Z"), "h
obby" : [ "eat", "drink", "play", "happy", "money", "mm" ] }
// 数组字段: 值,意思就是这个数组中是否包含该元素,如果包含就是满足条件的
> db.food.insert({"fruit": ["apple", "banana", "cherry"]})
WriteResult({ "nInserted" : 1 })
> db.food.find({"fruit": "banana"})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "apple", "banana", "cherry" ] }
// 当值是一个值时是是否包含,当值是数组时就是精确匹配了,此时匹配不到结果
> db.food.find({"fruit": ["apple", "cherry"]})
// $all: 数组中同时都包含多个元素
> db.food.find({"fruit": {$all: ["apple", "cherry"]}})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "apple", "banana", "cherry" ] }
// 查询数组中指定的下标对应的值是否和给的值一样
// 查询文档中的fruit中第三个元素的值是cherry的文档
> db.food.find({"fruit.2": "cherry"})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "apple", "banana", "cherry" ] }
>
// $size: 根据数组的长度进行筛选
> db.food.find({"fruit": {$size: 3}})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "apple", "banana", "cherry" ] }
> db.food.find()
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "apple", "banana", "orange", "cherry" ]
>
// 返回数组中前两个元素
> db.food.find({}, {"fruit": {$slice: 2}})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "apple", "banana" ] }
// 返回数组中后两个元素
> db.food.find({}, {"fruit": {$slice: -2}})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "orange", "cherry" ] }
// 偏移下标为1,取2个长度,相当于 limint 0, 2
> db.food.find({}, {"fruit": {$slice: [1, 2]}})
{ "_id" : ObjectId("597d353be210addac88b2a36"), "fruit" : [ "banana", "orange" ] }
>
> db.test.find()
{ "_id" : ObjectId("597d4342e210addac88b2a37"), "x" : [ 2, 5 ] }
{ "_id" : ObjectId("597d4350e210addac88b2a38"), "x" : [ 4, 5 ] }
{ "_id" : ObjectId("597d4367e210addac88b2a39"), "x" : [ 4, 10 ] }
// $elemMatch: 数组中是否有一个元素同时满足所有条件(只要有一个元素满足就能匹配上)
> db.test.find({"x": {"$elemMatch": {$gt: 5, $lt: 20}}})
{ "_id" : ObjectId("597d4367e210addac88b2a39"), "x" : [ 4, 10 ] }
// 根据字段的数据类型来查询,2代码String
> db.users.find({"username": {$type: 2}})
{ "_id" : 1, "username" : "mengday", "age" : 20, "birthday" : ISODate("2017-07-25T07:05:28.286Z") }
{ "_id" : 2, "username" : "tom", "age" : 18, "birthday" : ISODate("2017-07-25T07:05:52.166Z") }
{ "_id" : 3, "username" : "xiaohong", "age" : 28, "birthday" : ISODate("2017-07-25T07:06:13.741Z") }
{ "_id" : 4, "username" : "xiaoming", "age" : 27, "birthday" : ISODate("2017-07-25T07:06:44.812Z") }
{ "_id" : 5, "username" : "sunday", "age" : 37, "birthday" : ISODate("2017-07-25T07:07:45.420Z") }
{ "_id" : 6, "username" : "SunDay", "age" : 39, "birthday" : ISODate("2017-07-25T07:53:16.072Z"), "h
obby" : [ "eat", "drink", "play", "happy", "money", "mm" ] }
// 查询文档中没有username字段的或者username的值是null
> db.users.find({"username": null})
// 查询文档中存在username字段,并且值是null, $in:[null]和username:null 一样的效果
> db.users.find({"username": {$in: [null], $exists: true}})
{ "_id" : ObjectId("597c58f848c373e228a925a6"), "username" : null, "age" : 25 }
{ "_id" : ObjectId("597c591e48c373e228a925ab"), "username" : null, "age" : 24 }
// 自定义筛选条件,通过js函数返回的boolean值来筛选,可以实现复杂条件的筛选
> db.users.find({$where: function(){ return this.username == 'mengday' }})
{ "_id" : 1, "username" : "mengday", "age" : 20, "birthday" : ISODate("2017-07-25T07:05:28.286Z") }
// 运行命令: 平常使用的很多命令如db.test.drop()底层都是调用的db.runCommand({"函数名":参数值})来实现的
> db.runCommand({"drop": "test"})
{ "ns" : "test.test", "nIndexesWas" : 1, "ok" : 1 }
// db.getLastError 和 db.runCommand({getLastError: 1}) 是一样的
> db.getLastError
> db.runCommand({getLastError: 1})
### 游标
游标: 将查询结果赋值给一个局部变量,这个局部变量就是游标, 使用游标时shell并不理解查询数据库,而是等待真正开始要求获取结果时(调用hasNext()或者next()方法)才发送查询,这样在执行之前可以给查询附加额外的选项,如skip、limit、sort等,游标是一次性的,即用过一次即销毁
var cursor = db.users.find()
while(cursor.hasNext()){
user = cursor.next();
print(user);
}
// 需要重新查新赋值一个游标,上一个游标已经销毁
var cursor = db.users.find()
cursor.forEach(function(x){
print(x);
});
// 查询两条文档 , 相当于 select id, username from users limit 2
db.users.find({}, {“username”: 1}).limit(2)
{ “_id” : 1, “username” : “mengday” }
{ “_id” : 2, “username” : “tom” }
// 分页第一种方法使用skip和limit函数, skip(2) 是指的offset, 相当于 select id, username from users limit 2,2
db.users.find({}, {“username”: 1}).skip(2).limit(2)
{ “_id” : 3, “username” : “xiaohong” }
{ “_id” : 4, “username” : “xiaoming” }
// sort 排序, 1:升续, 2:降续
db.users.find({}, {“username”: 1}).skip(2).limit(2).sort({“age”: 1})
{ “_id” : 4, “username” : “xiaoming” }
{ “_id” : 3, “username” : “xiaohong” }
// 分页第二种方法:使用sort和limit函数
db.users.find()
{ “_id” : 1, “username” : “mengday1”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:52:33.837Z”) }
{ “_id” : 2, “username” : “mengday2”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:52:43.021Z”) }
{ “_id” : 3, “username” : “mengday3”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:52:53.420Z”) }
{ “_id” : 4, “username” : “mengday4”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:53:00.299Z”) }
{ “_id” : 5, “username” : “mengday5”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:53:07.826Z”) }
{ “_id” : 6, “username” : “mengday6”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:53:13.290Z”) }
{ “_id” : 7, “username” : “mengday7”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:54:36.710Z”) }
{ “_id” : 8, “username” : “mengday8”, “age” : 26, “create_date” : ISODate(“2017-07-30T07:54:40.262Z”) }
// 先根据日期进行排序,获取第一页数据时直接使用limit指定获取的条数,将结果赋值给局部变量,然后循环该游标,记录下最后一条文档对应的日期值
var page1 = db.users.find().sort({“create_date”: 1}).limit(5);
var latest = null;
while(page1.hasNext()){
… latest = page1.next();
… print(“page1:” + latest.username);
… }
page1:mengday1
page1:mengday2
page1:mengday3
page1:mengday4
page1:mengday5
// 获取后面的页:将上一页保存的文档对应的时间作为下一页查询的条件,因为还好对时间进行排序,又过滤掉之前的数据,相当于skip的效果,然后再获取指定的条数
var page2 = db.users.find({“create_date”: {$gt: latest.create_date}}).sort({“create_date”: 1}).limit(5);
while(page2.hasNext()){
… latest = page2.next();
… print(“page2:” + latest.username);
… }
page2:mengday6
page2:mengday7
page2:mengday8
### 聚合操作
// distinct: 查询某个字段的所有不重复的值, 相当于 select distinct age from users
db.users.distinct(“age”)
[ 20, 18, 28, 27, 37, 39 ]
// 分组: key: 要分组的字段, initial:值的初始化, condition:是筛选条件,$reduce:将满足的条件的所有文档都会执行该函数,finalize:每组函数执行完之后的操作,可以做一些统计什么的
db.users.group({
"key": {"age": true},
"initial": {"user": []},
"$reduce": function(cur, prev){
prev.user.push(cur) ;
},
"condition": {"age": {$lt:25}},
"finalize": function(out) {
out.count = out.user.length;
}
})
[
{
"age" : 20,
"user" : [
{
"_id" : 1,
"age" : 20,
"username" : "mengday20"
}
],
"count" : 1
},
{
"age" : 18,
"user" : [
{
"_id" : 2,
"username" : "tom",
"age" : 18,
"birthday" : ISODate("2017-07-25T07:05:52.166Z")
}
],
"count" : 1
}
]
>
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://monday.blog.csdn.net/article/details/76037827
内容来源于网络,如有侵权,请联系作者删除!