Mongodb学习笔记
1,下载并安装mongodb
①下载地址:https://www.mongodb.com/download-center?jmp=nav#community
将下载的mongodb-linux-x86_64-3.6.2.tgz放置在centos的usr目录下
网盘下载:https://pan.baidu.com/s/1c4dcdig
②解压:mongodb-linux-x86_64-3.6.2.tgz
进入mongodb-linux-x86_64-3.6.2文件夹创建一个db文件夹
③启动mongodb
命令:bin/mongod --dbpath=db
默认端口号:27017
2,下载并安装robomongo可视化工具
①下载地址:https://robomongo.org/
网盘下载:https://pan.baidu.com/s/1oAl5kT0
3,连接mongodb服务器
mongodb客户端一直连接不上centos的mongodb服务器
启动mongodb服务须加上--bind_ip_all(例如:bin/mongod --dbpath=db --auth --bind_ip_all)
给mongodb服务器设置密码:
①./mongo 连接mongodb服务器(./mongo --port 27017 -u "userAdmin" -p "123" --authenticationDatabase "admin")
②use admin 切换至admin数据库
③db.createUser({user: "userAdmin",pwd: "123",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]}) 创建管理员用户,并指定其权限
mongodb 对应 sqlserver
database=》database
collection=》table
document=》row
1,基本操作
①创建database
②创建collection
③创建document
1,capped collection(固定集合)
①可视化设置固定集合
②代码创建固定集合
1)简单创建固定集合
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
2)复杂创建固定集合
db.createCollection(<name>, { capped: <boolean>, autoIndexId: <boolean>, size: <number>, max: <number>, storageEngine: <document>, validator: <document>, validationLevel: <string>, validationAction: <string>, indexOptionDefaults: <document> } )
3)将集合转换为固定集合
db.runCommand({"convertToCapped": "mycoll", size: 100000});
4)查看collection的状态
db.log.stats()
5)倒序查询
db.log.find().sort( { $natural: -1 } )
参考文档:https://docs.mongodb.com/manual/reference/bson-types/
Type | Number | Alias | Notes |
---|---|---|---|
Double | 1 | “double” | |
String | 2 | “string” | |
Object | 3 | “object” | |
Array | 4 | “array” | |
Binary data | 5 | “binData” | |
Undefined | 6 | “undefined” | Deprecated. |
ObjectId | 7 | “objectId” | |
Boolean | 8 | “bool” | |
Date | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | Deprecated. |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | Deprecated. |
JavaScript (with scope) | 15 | “javascriptWithScope” | |
32-bit integer | 16 | “int” | |
Timestamp | 17 | “timestamp” | |
64-bit integer | 18 | “long” | |
Decimal128 | 19 | “decimal” | New in version 3.4. |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
1,通过find操作,用undefined做作为比较条件
printjson(db.mycollection.find({"name":{$type:6}}).toArray()); printjson(db.mycollection.find({"name":{$type:'undefined'}}).toArray());
2,Timestamps
var a = new Timestamp(); db.test.insertOne( { ts: a } );
1,创建和更改表
SQL | Mongodb |
CREATE TABLE people (
id MEDIUMINT NOT NULL
AUTO_INCREMENT,
user_id Varchar(30),
age Number,
status char(1),
PRIMARY KEY (id)
)
|
db.people.insertOne( { user_id: "abc123", age: 55, status: "A" } ) |
ALTER TABLE people
ADD join_date DATETIME
|
db.people.updateMany(
{ },
{ $set: { join_date: new Date() } }
)
|
ALTER TABLE people
DROP COLUMN join_date
|
db.people.updateMany(
{ },
{ $unset: { "join_date": "" } }
)
|
CREATE INDEX idx_user_id_asc
ON people(user_id)
|
db.people.createIndex( { user_id: 1 } ) |
CREATE INDEX
idx_user_id_asc_age_desc
ON people(user_id, age DESC)
|
db.people.createIndex( { user_id: 1, age: -1 } ) |
DROP TABLE people
|
db.people.drop() |
2,插入数据
SQL | Mongodb |
INSERT INTO people(user_id,
age,
status)
VALUES ("bcd001",
45,
"A")
|
db.people.insertOne(
{ user_id: "bcd001", age: 45, status: "A" }
)
|
3,查询数据
SQL | Mongodb |
SELECT *
FROM people
|
db.people.find()
|
SELECT id,
user_id,
status
FROM people
|
db.people.find(
{ },
{ user_id: 1, status: 1 }
)
|
SELECT user_id, status
FROM people
|
db.people.find(
{ },
{ user_id: 1, status: 1, _id: 0 }
)
|
SELECT *
FROM people
WHERE status = "A"
|
db.people.find(
{ status: "A" }
)
|
SELECT user_id, status
FROM people
WHERE status = "A"
|
db.people.find(
{ status: "A" },
{ user_id: 1, status: 1, _id: 0 }
)
|
SELECT *
FROM people
WHERE status != "A"
|
db.people.find(
{ status: { $ne: "A" } }
)
|
SELECT *
FROM people
WHERE status = "A"
AND age = 50
|
db.people.find(
{ status: "A",
age: 50 }
)
|
SELECT *
FROM people
WHERE status = "A"
OR age = 50
|
db.people.find(
{ $or: [ { status: "A" } ,
{ age: 50 } ] }
)
|
SELECT *
FROM people
WHERE age > 25
|
db.people.find(
{ age: { $gt: 25 } }
)
|
SELECT *
FROM people
WHERE age < 25
|
db.people.find(
{ age: { $lt: 25 } }
)
|
SELECT *
FROM people
WHERE age > 25
AND age <= 50
|
db.people.find(
{ age: { $gt: 25, $lte: 50 } }
)
|
SELECT *
FROM people
WHERE user_id like "%bc%"
|
db.people.find( { user_id: /bc/ } )
db.people.find( { user_id: { $regex: /bc/ } } )
|
SELECT *
FROM people
WHERE user_id like "bc%"
|
db.people.find( { user_id: /^bc/ } )
db.people.find( { user_id: { $regex: /^bc/ } } )
|
SELECT *
FROM people
WHERE status = "A"
ORDER BY user_id ASC
|
db.people.find( { status: "A" } ).sort( { user_id: 1 } ) |
SELECT *
FROM people
WHERE status = "A"
ORDER BY user_id DESC
|
db.people.find( { status: "A" } ).sort( { user_id: -1 } ) |
SELECT COUNT(*)
FROM people
|
db.people.count()
db.people.find().count()
|
SELECT COUNT(user_id)
FROM people
|
db.people.count( { user_id: { $exists: true } } )
db.people.find( { user_id: { $exists: true } } ).count()
|
SELECT COUNT(*)
FROM people
WHERE age > 30
|
db.people.count( { age: { $gt: 30 } } )
db.people.find( { age: { $gt: 30 } } ).count()
|
SELECT DISTINCT(status)
FROM people
|
db.people.aggregate( [ { $group : { _id : "$status" } } ] )
db.people.distinct( "status" )
|
SELECT *
FROM people
LIMIT 1
|
db.people.findOne()
db.people.find().limit(1)
|
SELECT *
FROM people
LIMIT 5
SKIP 10
|
db.people.find().limit(5).skip(10) |
EXPLAIN SELECT *
FROM people
WHERE status = "A"
|
db.people.find( { status: "A" } ).explain() |
4,修改数据
SQL | Mongodb |
UPDATE people
SET status = "C"
WHERE age > 25
|
db.people.updateMany(
{ age: { $gt: 25 } },
{ $set: { status: "C" } }
)
|
UPDATE people
SET age = age + 3
WHERE status = "A"
|
db.people.updateMany(
{ status: "A" } ,
{ $inc: { age: 3 } }
)
|
5,删除数据
SQL | Mongodb |
DELETE FROM people
WHERE status = "D"
|
db.people.deleteMany( { status: "D" } )
|
DELETE FROM people
|
db.people.deleteMany({})
|
比较运算符 | 备注 | 说明 | 用法 |
$eq | = | equal |
{ <field>: { $eq: <value> } }
|
$gt | > | greater than | {field: {$gt: value} } |
$gte | >= | greater than equal | {field: {$gte: value} } |
$lt | < | less than |
{field: {$lt: value} }
|
$lte | <= | less than equal | { field: { $lte: value} } |
$ne | != | not equal | {field: {$ne: value} } |
$in | in |
{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }
|
|
$nin | !in | not in | { field: { $nin: [ <value1>, <value2> ... <valueN> ]} } |
1,测试数据
db.inventory.insert([ { _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, { _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, { _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, { _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] }, { _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }])
2,案例
①查询qty>=20的数据
db.inventory.find({"qty":{$gte:20}})
②查询item对象中的name为ab的数据
db.inventory.find({"item.name":{$eq:"ab"}})
db.inventory.find({"item.name":"ab"})
③查询tags集合中包含C的数据
db.inventory.find({tags:{$in:["C"]}})
④查询出tags集合为[ [ "A", "B" ], "C" ]的数据
db.inventory.find({tags:{$eq:[["A","B"],"C"]}})
1,$and
①使用方法: { $and: [ { <expression1> }, { <expression2> } , ... , {<expressionN> } ] }
②案例
db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
db.inventory.find( { $and : [ { $or : [ { price : 0.99 }, { price : 1.99 } ] }, { $or : [ { sale : true }, { qty : { $lt : 20 } } ] } ] } )
2,$not
①使用方法: { field: { $not: { <operator-expression> } } }
②案例
db.inventory.find( { price: { $not: { $gt: 1.99 } } } )
db.inventory.find( { item: { $not: /^p.*/ } } )
3,$nor(or的反向)
①使用方法: { $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }
②案例
db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ] } )
db.inventory.find( { $nor: [ { price: 1.99 }, { qty: { $lt: 20 } }, { sale: true } ] } )
4,$or
①使用方法: { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
②案例
db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
1,$exists(判断存不存在字段)
①使用方法: { field: { $exists: <boolean> } }
②案例
db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )
2,$type
①使用方法: { field: { $type: <BSON type> } }
②案例
db.addressBook.find( { "zipCode" : { $type : "number" } } )
1,$expr【允许在查询语言中使用聚合表达式。】
①使用方法: { $expr: { <expression> } }
②案例
1)查询花费大于预算
{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 } { "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 } { "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 } { "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 } { "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
db.monthlyBudget.find({$expr:{$gt:[ "$spent","$budget" ]}})
2)qty>=100的情况(price/2)<5;qty<100的情况(price/4)<5
{ "_id" : 1, "item" : "binder", "qty": 100 , "price": 12 } { "_id" : 2, "item" : "notebook", "qty": 200 , "price": 8 } { "_id" : 3, "item" : "pencil", "qty": 50 , "price": 6 } { "_id" : 4, "item" : "eraser", "qty": 150 , "price": 3 }
db.supplies.find( { $expr: { $lt:[ { $cond: { if: { $gte: ["$qty", 100] }, then: { $divide: ["$price", 2] }, else: { $divide: ["$price", 4] } } }, 5 ] } } )
2,$jsonSchema【根据给定的JSON模式验证文档】
①使用方法: { $jsonSchema: <schema> }
参照文档:https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/#op._S_jsonSchema
3,$mod【取模运算】
①使用方法: { field: { $mod: [ 除数, 余] } }
②案例
{ "_id" : 1, "item" : "abc123", "qty" : 0 } { "_id" : 2, "item" : "xyz123", "qty" : 5 } { "_id" : 3, "item" : "ijk123", "qty" : 12 }
捞出qty除4余0的数据
db.inventory.find( { qty: { $mod: [ 4, 0 ] } } )
3,$regex【选择值与指定正则表达式匹配的文档】
①使用方法: { <field>: /pattern/<options> }
{ <field>: { $regex: /pattern/, $options: '<options>' } } { <field>: { $regex: 'pattern', $options: '<options>' } } { <field>: { $regex: /pattern/<options> } }
Option | 描述 | 语法限制 |
---|---|---|
i |
不区分大小写 | |
m |
对于包含锚的模式(即起始为^,结束为$),在每行的开始或结束处匹配具有多行值的字符串。 没有这个选项,这些锚点匹配字符串的开头或结尾。 有关示例,请参阅多行匹配以指定模式开始的行。 |
|
x |
忽略$regex模式中的所有空格字符,除非转义或包含在字符类中 |
需要使用$ options语法的$ regex |
s |
允许点字符匹配包括换行符的所有字符 | 需要使用$ options语法的$ regex |
②案例
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." } { "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" } { "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" } { "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
查询sku789结尾的数据(忽略大小写)
db.products.find( { sku: { $regex: /789$/ } } )
db.products.find( { sku:/789$/i } )
4,$text【全文搜索。不支持中文】
①使用方法:
{ $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } }
参考文档:https://docs.mongodb.com/manual/reference/operator/query/text/#op._S_text
5,$where【匹配满足JavaScript表达式的文档】
①案例
{ _id: 12378, name: "Steve", username: "steveisawesome", first_login: "2017-01-01" } { _id: 2, name: "Anya", username: "anya", first_login: "2001-02-02" }
db.foo.find( { $where: function() { return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994") } } );
1,$all【匹配包含查询中指定的所有元素的数组】
①使用方法: { <field>: { $all: [ <value1> , <value2> ... ] } }
②案例
{ _id: ObjectId("5234cc89687ea597eabee675"), code: "xyz", tags: [ "school", "book", "bag", "headphone", "appliance" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 45, color: "blue" }, { size: "L", num: 100, color: "green" } ] } { _id: ObjectId("5234cc8a687ea597eabee676"), code: "abc", tags: [ "appliance", "school", "book" ], qty: [ { size: "6", num: 100, color: "green" }, { size: "6", num: 50, color: "blue" }, { size: "8", num: 100, color: "brown" } ] } { _id: ObjectId("5234ccb7687ea597eabee677"), code: "efg", tags: [ "school", "book" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 100, color: "blue" }, { size: "L", num: 100, color: "green" } ] } { _id: ObjectId("52350353b2eff1353b349de9"), code: "ijk", tags: [ "electronics", "school" ], qty: [ { size: "M", num: 100, color: "green" } ] }
集合中包含"appliance", "school", "book" 的文档
db.inventory.find( { tags: { $all: [ "appliance", "school", "book" ] } } )
2,$elemMatch【如果数组中的元素匹配所有指定的$ elemMatch条件,则选择文档】
①使用方法: { <field>: { $elemMatch: { <query1>, <query2>, ... } } }
②案例
{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] } { _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] } { _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
db.survey.find( { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } )
3,$size【如果数组字段是指定的大小,则选择文档。】
db.collection.find( { field: { $size: 2 } } );
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ] } )
Parameter | Type | Description |
---|---|---|
query |
document |
更新筛选条件 |
update |
document | 修改 |
upsert |
boolean | 可选的。 如果设置为true,则在没有文档匹配查询条件时创建一个新文档。 默认值为false,当找不到匹配项时不插入新文档。 |
multi |
boolean | 可选的。 如果设置为true,则更新符合查询条件的多个文档。 如果设置为false,则更新一个文档。 默认值是false。 有关其他信息,请参阅多参数。 |
writeConcern |
document |
可选的。 表达写入关注的文档。 省略使用默认的写入问题 |
collation |
document |
可选的。 指定用于操作的排序规则。 整理允许用户为字符串比较指定特定于语言的规则 排序选项具有以下语法: collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}
指定排序规则时,语言环境字段是强制性的; 所有其他整理字段是可选的。 有关这些字段的说明,请参阅整理文档。 如果排序规则未指定,但该集合具有默认排序规则(请参阅db.createCollection()),则该操作使用为该集合指定的排序规则。 如果没有为集合或操作指定排序规则,则MongoDB使用先前版本中使用的简单二进制比较进行字符串比较。 您无法为操作指定多个归类。 例如,不能为每个字段指定不同的排序规则,或者如果使用排序来执行查找,则不能使用一个排序规则查找,另一个排序规则。 |
arrayFilters |
array |
可选的。 一组过滤器文档,用于确定要修改阵列字段上的更新操作的数组元素。 在更新文档中,使用$ [<identifier>]过滤位置运算符来定义标识符,然后在阵列过滤器文档中引用该标识符。 如果标识符未包含在更新文档中,则不能拥有标识符的数组筛选器文档。 注意 <identifier>必须以小写字母开头,并且只包含字母数字字符。 您可以在更新文档中多次包含相同的标识符; 但是,对于更新文档中的每个不同标识符($ [identifier]),必须正好指定一个相应的数组过滤器文档。 也就是说,不能为同一个标识符指定多个数组过滤器文档。 例如,如果更新语句包含标识符x(可能多次),则不能为arrayFilters指定以下值: [ { "x.a": { $gt: 85} }, { "x.b": { $gt: 80 } } ]
但是,您可以在单个数组过滤器文档中的相同标识符上指定复合条件,例如: [ { $or: [ { "x.a": { $gt: 85} }, { "x.b": { $gt: 80 } } ] } ]
[ { $and: [ { "x.a": { $gt: 85} }, { "x.b": { $gt: 80 } } ] } ]
|
1,$currentDate【将字段的值设置为当前日期,可以是日期或时间戳】
①使用方法: { $currentDate: { <field1>: <typeSpecification1>, ... } }
②案例
{ _id: 1, status: "a", lastModified: ISODate("2013-10-02T01:11:18.965Z") }
db.users.update({_id:2},{$currentDate:{lastModified:{ $type: "date" }}})
2,$inc【按指定的量增加字段的值】
①使用方法: { $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
②案例
{ _id: 1, sku: "abc123", quantity: 10, metrics: { orders: 2, ratings: 3.5 } }
db.products.update( { sku: "abc123" }, { $inc: { quantity: -2, "metrics.orders": 1 } } )
3,$min【如果指定的值小于现有字段值,则只更新字段】
①使用方法: { $min: { <field1>: <value1>, ... } }
②案例
{ _id: 1, highScore: 800, lowScore: 200 }
比原有lowScore的值小则更新
db.scores.update( { _id: 1 }, { $min: { lowScore: 150 } } )
4,$max【如果指定的值大于现有字段值,则只更新字段】
①使用方法: { $max: { <field1>: <value1>, ... } }
②案例
{ _id: 1, highScore: 800, lowScore: 200 }
比原有highScore的值大则更新
db.scores.update( { _id: 1 }, { $max: { highScore: 950 } } )
5,$mul【将字段的值乘以指定的数量】
①使用方法: { $mul: { field: <number> } }
②案例
{ _id: 1, item: "ABC", price: 10.99 }
price值乘1.25
db.products.update( { _id: 1 }, { $mul: { price: 1.25 } } )
6,$rename【重命名一个字段】
①使用方法: {$rename: { <field1>: <newName1>, <field2>: <newName2>, ... } }
②案例
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )
7,$set【设置文档中字段的值】
①使用方法: { $set: { <field1>: <value1>, ... } }
②案例
{ _id: 100, sku: "abc123", quantity: 250, instock: true, reorder: false, details: { model: "14Q2", make: "xyz" }, tags: [ "apparel", "clothing" ], ratings: [ { by: "ijk", rating: 4 } ] }
db.products.update( { _id: 100 }, { $set: { quantity: 500, details: { model: "14Q3", make: "xyz" }, tags: [ "coats", "outerwear", "clothing" ] } } )
db.products.update( { _id: 100 }, { $set: { "details.make": "zzz" } } )
db.products.update( { _id: 100 }, { $set: { "tags.1": "rain gear", "ratings.0.rating": 2 } } )
8,$setOnInsert【如果更新导致插入文档,则设置字段的值。 对修改现有文档的更新操作没有影响】
db.products.update( { _id: 1 }, { $set: { item: "apple" }, $setOnInsert: { defaultQty: 200 } }, { upsert: true } )
upsert: true表示没有数据则插入;false表示没有数据则什么也不做
$setOnInsert: { defaultQty: 200 }表示只有插入时才会将defaultQty设置为 200。更新操作不会设置此值
9,$unset【从文档中删除指定的字段】
①使用方法: { $unset: { <field1>: "", ... } }
②案例
db.products.update( { _id: 2 }, {$unset:{item:""}} )
1,$ 【充当占位符来更新匹配查询条件的第一个元素】
①使用方法: { "<array>.$" : value }
②案例
db.students.insert([ { "_id" : 1, "grades" : [ 85, 80, 80 ] }, { "_id" : 2, "grades" : [ 88, 90, 92 ] }, { "_id" : 3, "grades" : [ 85, 100, 90 ] } ])
id为1的项,将第一个grades为80的项改为82
db.students.update( { _id: 1, grades: 80 }, { $set: { "grades.$" : 82 } } )
2,$[] 【充当占位符来更新数组中与查询条件匹配的所有元素】
①使用方法: { <update operator>: { "<array>.$[]" : value } }
②案例
id为1的项,将grades所有项改为80
db.students.update( { _id: 1, grades: 82 }, { $set: { "grades.$[]" : 80 } } )
3,$[<identifier>] 【充当占位符以更新与匹配查询条件的文档的arrayFilters条件匹配的所有元素】
①使用方法:
{ <update operator>: { "<array>.$[<identifier>]" : value } }, { arrayFilters: [ { <identifier>: <condition> } } ] }
②案例
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 102 ] } { "_id" : 3, "grades" : [ 95, 110, 100 ] }
db.students.update( { }, { $set: { "grades.$[element]" : 100 } }, { multi: true, arrayFilters: [ { "element": { $gte: 100 } } ] } )
4,$addToSet 【只有在数组中不存在元素的情况下,才能将元素添加到数组中】
①使用方法: { $addToSet: { <field1>: <value1>, ... } }
②案例
{ _id: 1, letters: ["a", "b"] }
db.test.update({_id:1},{$addToSet:{"letters":"e"}})
db.test.update({_id:1},{$addToSet:{"letters": {$each: [ "camera", "electronics", "accessories" ]}}})
5,$pop 【删除数据中的最后一个或第一个】
①使用方法: { $pop: { <field>: <-1 | 1>, ... } }
-1:弹出第一个;1:弹出最后一个
②案例
{ "_id" : 1, "letters" : [ "d", "camera", "electronics", "accessories" ] }
db.test.update({_id:1},{$pop:{"letters":-1}})
6,$pull 【删除所有匹配指定查询的数组元素】
①使用方法: { $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
②案例
{ _id: 1, fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ], vegetables: [ "carrots", "celery", "squash", "carrots" ] } { _id: 2, fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ], vegetables: [ "broccoli", "zucchini", "carrots", "onions" ] }
db.stores.update( { }, { $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } }, { multi: true } )
{ _id: 1, results: [ { item: "A", score: 5 }, { item: "B", score: 8, comment: "Strongly agree" } ] } { _id: 2, results: [ { item: "C", score: 8, comment: "Strongly agree" }, { item: "B", score: 4 } ] }
db.survey.update( { }, { $pull: { results: { score: 8 , item: "B" } } }, { multi: true } )
7,$push 【将一个项添加到数组中】
①使用方法: { $push: { <field1>: <value1>, ... } }
Modifier | Description |
---|---|
$each |
将多个值附加到数组字段 |
$slice |
限制数组元素的数量。 需要使用$ each修饰符。 |
$sort |
排序 1:升序 -1:降序 |
$position |
指定数组中插入新元素的位置。 需要使用$ each修饰符。 如果没有$ position修饰符,$ push会将元素附加到数组的末尾。 |
②案例
db.students.update( { _id: 1 }, { $push: { quizzes: { $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ], $sort: { score: 1 } } } } )
db.students.update( { _id: 2 }, { $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } } )
db.students.update( { _id: 6 }, { $push: { quizzes: { $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], $sort: { score: -1 }, $slice: 2 //限制长度,多了会截取 } } }, { upsert:true} )
8,$pullAll 【从数组中删除所有匹配的值】
①使用方法: { $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } }
②案例
{ _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] }
db.survey.update( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } )
9,$each【修改$push和$addToSet操作符以追加多个项目进行数组更新】
①使用方法:
{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
{ $push: { <field>: { $each: [ <value1>, <value2> ... ] } } }
②案例
db.students.update( { name: "joe" }, { $push: { scores: { $each: [ 90, 92, 85 ] } } } )
db.inventory.update( { _id: 2 }, { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } } )
10,$position【修改$push操作符以指定数组中的位置以添加元素】
①使用方法:
{ $push: { <field>: { $each: [ <value1>, <value2>, ... ], $position: <num> } } }
②案例
{ "_id" : 1, "scores" : [ 100 ] }
db.students.update( { _id: 1 }, { $push: { scores: { $each: [ 50, 60, 70 ], $position: 0 } } } )
{ "_id" : 1, "scores" : [ 50, 60, 70, 100 ] }
11,$slice【修改$push操作符以限制更新数组的大小】
①使用方法:
{ $push: { <field>: { $each: [ <value1>, <value2>, ... ], $slice: <num> } } }
Value | Description |
---|---|
0 | 将数组更新为一个空数组([]) |
负数 | 保留数据最后一位,数组超出大小从左边开始截取 |
正数 |
保留第一位,数组超出大小从右边开始截取 |
②案例
1)将grades数组更新空数组
db.students.update( { _id: 1 }, { $push: { grades: { $each: [ 1,2,4 ], $sort: { score: -1 }, $slice: 0 } } } )
2)插入1,2,4 只会保留4
db.students.update( { _id: 1 }, { $push: { grades: { $each: [ 1,2,4 ], $sort: { score: -1 }, $slice: -1 } } } )
3)插入1,2,4 只会保留1
db.students.update( { _id: 1 }, { $push: { grades: { $each: [ 1,2,4 ], $sort: { score: -1 }, $slice:1 } } } )
12,$sort【修改$ push操作符以重新排列存储在数组中的文档】
①使用方法:
{ $push: { <field>: { $each: [ <value1>, <value2>, ... ], $sort: <sort specification> } } }
1指定为升序,-1指定为降序。
②案例
{ "_id": 1, "quizzes": [ { "id" : 1, "score" : 6 }, { "id" : 2, "score" : 9 } ] }
db.students.update( { _id: 1 }, { $push: { quizzes: { $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ], $sort: { score: 1 } } } } )
{ "_id" : 1, "quizzes" : [ { "id" : 1, "score" : 6 }, { "id" : 5, "score" : 6 }, { "id" : 4, "score" : 7 }, { "id" : 3, "score" : 8 }, { "id" : 2, "score" : 9 } ] }
{ "_id" : 2, "tests" : [ 89, 70, 89, 50 ] }
db.students.update( { _id: 2 }, { $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } } )
{ "_id" : 2, "tests" : [ 40, 50, 60, 70, 89, 89 ] }
{ "_id" : 3, "tests" : [ 89, 70, 100, 20 ] }
db.students.update( { _id: 3 }, { $push: { tests: { $each: [ ], $sort: -1 } } } )
{ "_id" : 3, "tests" : [ 100, 89, 70, 20 ] }
1,$bit【执行整数值的按位AND,OR和XOR更新。】
①使用方法: { $bit: { <field>: { <and|or|xor>: <int> } } }
②案例
{ _id: 1, expdata: NumberInt(13) } db.switches.update( { _id: 1 }, { $bit: { expdata: { and: NumberInt(10) } } } ) 1101 1010 ---- 1000
{ "_id" : 1, "expdata" : 8 }
{ _id: 2, expdata: NumberLong(3) } db.switches.update( { _id: 2 }, { $bit: { expdata: { or: NumberInt(5) } } } ) 0011 0101 ---- 0111 { "_id" : 2, "expdata" : NumberLong(7) }
{ _id: 3, expdata: NumberLong(1) } db.switches.update( { _id: 3 }, { $bit: { expdata: { xor: NumberInt(5) } } } ) 0001 0101 ---- 0100 { "_id" : 3, "expdata" : NumberLong(4) }
1,Insert
1)db.collection.insertOne()【将单个文档插入到一个集合中】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.insertOne/#db.collection.insertOne
db.collection.insertOne( <document>, { writeConcern: <document> } )
2)db.collection.insertMany()【将多个文档插入到一个集合中】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/#db.collection.insertMany
db.collection.insertMany( [ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> } )
3)db.collection.insert()【将单个文档或多个文档插入到集合中】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.insert/#db.collection.insert
db.collection.insert( <document or array of documents>, { writeConcern: <document>, ordered: <boolean> } )
2,Query
1)查询嵌入式/嵌套文档
db.inventory.insertMany( [ { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" }, { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" }, { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" }, { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" } ]);
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } ) db.inventory.find( { "size.uom": "in" } ) db.inventory.find( { "size.h": { $lt: 15 } } ) db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )
2)查询数组
db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] }, { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] }, { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] }, { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] }, { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } ]);
db.inventory.find( { tags: ["red", "blank"] } ) db.inventory.find( { tags: { $all: ["red", "blank"] } } ) db.inventory.find( { tags: "red" } ) db.inventory.find( { dim_cm: { $gt: 25 } } ) db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } ) db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } ) db.inventory.find( { "dim_cm.1": { $gt: 25 } } ) db.inventory.find( { "tags": { $size: 3 } } )
3)查询嵌入式文档数组
db.inventory.insertMany( [ { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] }, { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] }, { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] }, { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] }, { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] } ]);
db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } ) db.inventory.find( { 'instock.qty': { $lte: 20 } } ) db.inventory.find( { 'instock.0.qty': { $lte: 20 } } ) db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } ) db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } ) db.inventory.find( { "instock.qty": { $gt: 10, $lte: 20 } } ) db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )
4)返回指定的字段
db.inventory.insertMany( [ { item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] }, { item: "notebook", status: "A", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] }, { item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] }, { item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] }, { item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] } ]);
db.inventory.find( { status: "A" }, { item: 1, status: 1 } ) SELECT _id, item, status from inventory WHERE status = "A"
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } ) SELECT item, status from inventory WHERE status = "A"
5)查询空字段或缺少字段
db.inventory.insertMany([ { _id: 1, item: null }, { _id: 2 } ])
db.inventory.find( { item: null } ) db.inventory.find( { item : { $type: 10 } } ) db.inventory.find( { item : { $exists: false } } )
6)迭代游标
var myCursor = db.users.find( { type: 2 } ); while (myCursor.hasNext()) { print(tojson(myCursor.next())); }
var myCursor = db.users.find( { type: 2 } ); while (myCursor.hasNext()) { printjson(myCursor.next()); }
var myCursor = db.users.find( { type: 2 } ); myCursor.forEach(printjson);
var myCursor = db.inventory.find( { type: 2 } ); var documentArray = myCursor.toArray(); var myDocument = documentArray[3];
var myCursor = db.users.find( { type: 2 } ); var myDocument = myCursor[1];
3,Update
1)db.collection.updateOne() 【即使多个文档可能与指定的过滤器匹配,也会更新与指定过滤器匹配的单个文档】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/#db.collection.updateOne
db.collection.updateOne( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ] } )
2)db.collection.updateMany() 【更新所有匹配指定过滤器的文档】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#db.collection.updateMany
db.collection.updateMany( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ] } )
3)db.collection.replaceOne() 【即使多个文档可能与指定的过滤器匹配,也只能替换与指定过滤器匹配的单个文档】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#db.collection.replaceOne
db.collection.replaceOne( <filter>, <replacement>, { upsert: <boolean>, writeConcern: <document>, collation: <document> } )
4)db.collection.update()
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.update/#db.collection.update
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ] } )
更新或替换与指定过滤器匹配的单个文档,或更新与指定过滤器匹配的所有文档。
默认情况下,db.collection.update()方法更新单个文档。 要更新多个文档,请使用multi选项。
4,Delete
1)db.collection.deleteOne() 【即使多个文档可能匹配指定的过滤器,也最多删除与指定过滤器匹配的单个文档】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.deleteOne/#db.collection.deleteOne
db.collection.deleteOne( <filter>, { writeConcern: <document>, collation: <document> } )
2)db.collection.deleteMany() 【删除所有匹配指定过滤器的文档】
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.deleteMany/#db.collection.deleteMany
db.collection.deleteMany( <filter>, { writeConcern: <document>, collation: <document> } )
3)db.collection.remove() 【删除单个文档或与指定过滤器匹配的所有文档】.
详细文档:https://docs.mongodb.com/manual/reference/method/db.collection.remove/#db.collection.remove
db.collection.remove( <query>, <justOne> )
justOne(true:删除一个。false:删除多个)。默认为false
db.students.find({}).explain() //查询执行计划
1,Single Field Indexes(单键索引)
详细文档:https://docs.mongodb.com/manual/core/index-single/#create-an-index-on-an-embedded-field
1)在单个字段上创建升序索引
{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" } } db.records.createIndex( { score: 1 } )
2)在嵌入式字段上创建索引
{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" } } db.records.createIndex( { "location.state": 1 } )
3)在嵌入式文档上创建一个索引
{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" } } db.records.createIndex( { location: 1 } )
2,Compound Indexes(复合索引)
详细文档:https://docs.mongodb.com/manual/core/index-compound/
1)创建一个复合索引
{ "_id": ObjectId(...), "item": "Banana", "category": ["food", "produce", "grocery"], "location": "4th Street Store", "stock": 4, "type": "cases" } db.products.createIndex( { "item": 1, "stock": 1 } )
3,Multikey Indexes(多键索引)
详细文档:https://docs.mongodb.com/manual/core/index-multikey/
要索引一个包含数组值的字段,MongoDB会为数组中的每个元素创建一个索引键
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] } { _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] } { _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] } { _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] } { _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] } db.inventory.createIndex( { ratings: 1 } )
4,Hashed Indexes(hash索引)
详细文档:https://docs.mongodb.com/manual/core/index-hashed/
db.collection.createIndex( { _id: "hashed" } )
5,Partial Indexes(局部索引)
使用更小的空间提高部分性能
1)例如,以下操作将创建仅索引defaultQty字段大于200的文档的复合索引。
db.products.createIndex({defaultQty:1},{ partialFilterExpression: { defaultQty: { $gt: 200 } } })
6,Unique Indexes(唯一索引)
db.members.createIndex( { "user_id": 1 }, { unique: true } )
7,Sparse Indexes(稀疏索引)
详细文档:https://docs.mongodb.com/manual/core/index-sparse/
即使索引字段包含空值,稀疏索引也只包含具有索引字段的文档的条目。 索引跳过缺少索引字段的任何文档。 索引是“稀疏的”,因为它不包含集合的所有文档。 相比之下,非稀疏索引包含集合中的所有文档,为那些不包含索引字段的文档存储空值。
1)创建一个稀疏索引(使用a作为条件时会IXSCAN)
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "a" : "a" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "b" : "b" } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "c" : "c"} db.scores.createIndex( { a: 1 } , { sparse: true } )
2)只查询包含稀疏索引的字段(a)
db.getCollection('test').find().hint({ a: 1 }) 结果: /* 1 */ { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "a" : "a" }
8,TTL Indexes(过期索引)
详细文档:https://docs.mongodb.com/manual/core/index-ttl/
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
expireAfterSeconds:过期秒数
注:mongodb每60s执行一次task。所以把过期时间设置的过短,也会60s执行一次
db.dates.insert({ lastdate:new Date(), a:"a" }) db.dates.createIndex({"lastdate":1},{expireAfterSeconds:1})
1,何时使用GridFS?
在MongoDB中,使用GridFS存储大于16 MB的文件。
2,GridFS集合
GridFS将文件存储在两个集合中:
chunks
(fs.chunks)存储二进制块files
(fs.files)存储文件的元数据
{ "_id" : <ObjectId>, //chunk的唯一ObjectId。 "files_id" : <ObjectId>, //文件集合中指定的“父”文档的_id。 "n" : <num>, //chunk的序列号。 GridFS将所有chunk从0开始编号。 "data" : <binary> //二进制 }
{ "_id" : <ObjectId>, //此文档的唯一标识符 "length" : <num>, //文档的大小(以字节为单位) "chunkSize" : <num>, //每个块的大小(以字节为单位)默认大小是255千字节(kB) "uploadDate" : <timestamp>,//GridFS首次存储文档的日期 "md5" : <hash>,// "filename" : <string>,//可选的。 GridFS文件的可读名称。 "contentType" : <string>,//可选的。 GridFS文件的有效MIME类型。 "aliases" : <string array>,//可选的。 一组别名字符串。 "metadata" : <any>,//可选的。 元数据字段可以是任何数据类型,并且可以保存您想要存储的任何附加信息 }
3,这个 fs.chunks的索引
GridFS使用files_id和n字段在块集合上使用唯一的复合索引。 这可以有效地检索块,如以下示例所示:
db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )
如果此索引不存在,则可以发出以下操作以使用mongo shell创建它:
db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );
4,这个 fs.files的索引
GridFS使用文件名和uploadDate字段在文件集合上使用索引。 这个索引允许高效地检索文件,如下例所示:
db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )
如果此索引不存在,则可以发出以下操作以使用mongo shell创建它:
db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );
6,使用mongofiles命令行工具上传文件
详细文档:https://docs.mongodb.com/manual/reference/program/mongofiles/#bin.mongofiles
所有mongofiles命令都具有以下形式: mongofiles <options> <commands> <filename>
mongofiles命令的组件是:
- Options. 您可以使用一个或多个这些选项来控制mongofiles的行为
- Commands. 使用这些命令之一来确定mongofiles的操作
- 一个文件名,它可以是:本地文件系统上的文件名称,也可以是GridFS对象.
1)案例
① 上传文件
[root@localhost bin]# ./mongofiles -d test put ./sp.3gp
②查看test数据库
参考文档:https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/#db.collection.aggregate
注意:因为是管道执行,则需要注意执行顺序
1,使用方式: db.collection.aggregate(pipeline, options)¶
pipeline:管道
options:可选的。 aggregate()传递给聚合命令的其他选项。
管道:
Name | Description |
---|---|
$addFields |
将新字段添加到文档。 输出包含输入文档和新添加字段中所有现有字段的文档。 |
$bucket |
根据指定的表达式和存储区边界将传入文档分组到称为存储桶的组中。 |
$bucketAuto |
根据指定的表达式将传入文档分类到特定数量的组(称为存储桶)。 桶边界自动确定,试图将文档均匀分布到指定数量的桶中。 |
$collStats |
返回有关集合或视图的统计信息。 |
$count |
返回聚合管道此阶段的文档数量。 |
$currentOp |
返回有关MongoDB部署的活动和/或休眠操作的信息。 要运行,请使用db.aggregate()方法。 |
$facet |
在同一组输入文档中的单个阶段内处理多个聚合流水线。 支持创建多方面的聚合,能够在单个阶段中跨多个维度或方面表征数据。 |
$geoNear |
根据地理空间点的接近度返回有序的文档流。 包含地理空间数据的$ match,$ sort和$ limit功能。 输出文件包含一个额外的距离字段,并可包含位置标识符字段。 |
$graphLookup |
对集合执行递归搜索。 为每个输出文档添加一个新的数组字段,其中包含该文档的递归搜索的遍历结果。 |
$group |
分组计算 |
$indexStats |
查询过程中的索引情况 |
$limit |
返回制指定数量的文档 |
$listLocalSessions |
列出当前连接的mongos或mongodinstance上最近使用的所有活动会话。 这些会话可能尚未传播到system.sessions集合。 |
$listSessions |
列出所有活动时间足以传播到system.sessions集合的所有会话。 |
$lookup |
表连接 |
$match |
相当于我们的 where |
$out |
将最后的结果输出到指定的collection中去 |
$project |
相当于我们sql操作的 select |
$redact |
根据存储在文档本身中的信息限制每个文档的内容,重新整形流中的每个文档。 包含$ project和$ match的功能。 可用于实施字段级别的编校。 对于每个输入文档,输出一个或零个文档。 |
$replaceRoot |
用指定的嵌入式文档替换文档。 该操作将替换输入文档中的所有现有字段,包括_id字段。 指定嵌入在输入文档中的文档以将嵌入式文档提升到顶层。 |
$sample |
从其输入中随机选择指定数量的文档。 |
$skip |
跳过前n个文档 |
$sort |
通过指定的排序键对文档流进行重新排序。 只有订单改变了; 文件保持不变。 对于每个输入文档,输出一个文档。 |
$sortByCount |
根据指定表达式的值对传入文档分组,然后计算每个不同组中文档的数量。 |
$unwind |
将数据拆解成每一个document |
2,案例
①分组并计算amount的总和
{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 } { _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 } { _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 } { _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 } { _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
db.orders.aggregate([ {$match:{status:"A"}}, {$group:{_id:"$cust_id",total:{$sum:"$amount"}}}, {$sort:{total:-1}} ])
②返回①的执行计划
db.orders.aggregate([ {$match:{status:"A"}}, {$group:{_id:"$cust_id",total:{$sum:"$amount"}}}, {$sort:{total:-1}} ], { explain:true } )
③分页
db.orders.aggregate([ {$match:{status:"A"}}, {$group:{_id:"$cust_id",total:{$sum:"$amount"}}}, {$sort:{total:-1}}, {$skip:1},//跳过一条 {$limit:2}//返回两条数据 ])
db.orders.find().skip(0).limit(10)//普通分页
③表连接
db.orders.insert([ { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 }, { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 }, { "_id" : 3 } ]) db.inventory.insert([ { "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 }, { "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 }, { "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 }, { "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 }, { "_id" : 5, "sku": null, description: "Incomplete" }, { "_id" : 6 } ])
db.orders.aggregate([ { $lookup:{ from:"inventory", localField:"item", foreignField:"sku", as:"inventory_docs" } } ])
详细文档:https://docs.mongodb.com/manual/reference/command/group/
使用方法:
{ group: { ns: <namespace>, key: <key>, $reduce: <reduce function>, $keyf: <key function>, cond: <query>, finalize: <finalize function> } }
ns:collections 你group的集合。。。
key: 我们group的键值。。
$keyf: 采用函数的定义我们的key, 我们可以后更高的灵活性来定义(去string的最后一个字母,或者中间,或者最后)
$reduce: 刚好就是我们聚合进行中的每个操作。。。
$initial: 聚合的初始文档。。。
cond: ($match) where条件
finalize: 在某一个groupkey结束后插入点。。。。
1,案例:
{ "_id" : 1, "sku" : "abc", "description" : "product 1", "instock" : 120 } { "_id" : 2, "sku" : "def", "description" : "product 2", "instock" : 80 } { "_id" : 3, "sku" : "ijk", "description" : "product 3", "instock" : 60 } { "_id" : 4, "sku" : "jkl", "description" : "product 4", "instock" : 70 } { "_id" : 5, "sku" : "abcedfe", "description" : "product 1", "instock" : 120 } { "_id" : 6, "sku" : "def而微软为", "description" : "product 2", "instock" : 70 }
db.runCommand( { group: { ns: 'test', key: { "description":1 }, //分组的key cond: { "_id":{$gt:1} }, //筛选条件 $reduce: function ( curr, result ) { //curr: 当前当前得到的document //result: 第一次就是我们目前的initial,后续的话看你怎么对result进行操作 result.count++; return result.total+=curr.instock; }, initial: {"total":0,"count":0 }, //初始化文档 finalize:function(result){ //结束执行 result.avg=result.total/result.count; } } } ) db.runCommand( { group: { ns: 'test', //key: { "description":1 }, //分组的key $keyf:function(doc){ return {"description":1} //doc: 当前的文档 }, cond: { "_id":{$gt:1} }, $reduce: function ( curr, result ) { //curr: 当前当前得到的document //result: 第一次就是我们目前的initial,后续的话看你怎么对result进行操作 result.count++; return result.total+=curr.instock; }, initial: {"total":0,"count":0 }, finalize:function(result){ result.avg=result.total/result.count; } } } )
参考文档:https://docs.mongodb.com/manual/reference/command/distinct/
使用方法:
{ distinct: "<collection>", key: "<field>", query: <query>, readConcern: <read concern document>, collation: <collation document> }
案例: db.runCommand ( { distinct: "test", key: "description" } )
参考文档:https://docs.mongodb.com/manual/reference/method/db.collection.mapReduce/index.html
使用方法:
db.collection.mapReduce( <map>, <reduce>, { out: <collection>, query: <document>, sort: <document>, limit: <number>, finalize: <function>, scope: <document>, jsMode: <boolean>, verbose: <boolean>, bypassDocumentValidation: <boolean> } )
Parameter | Type | Description |
---|---|---|
map |
function |
一个JavaScript函数,该函数将一个值与一个键关联或“映射”,并发出键和值对。 |
reduce |
function |
一个JavaScript函数,它“减少”到一个对象,所有的值都与一个特定的键相关联。 |
options |
document | 其他参数选项 |
bypassDocumentValidation |
boolean |
可选的。允许mapReduce在操作过程中绕过文档验证。这允许您插入不符合验证要求的文档。 |
Field | Type | Description |
---|---|---|
out |
string or document |
指定map-reduce操作结果的位置。您可以输出到一个集合,输出到一个具有动作的集合,或者内联(inline)输出。在对集合的主要成员执行map-reduce操作时,可以输出到集合;对于次要成员,您可能只使用内联(inline)输出。 |
query |
document | 条件 |
sort |
document | 排序 |
limit |
number | 指定输入到map函数的最大文档数。 |
finalize |
function |
可选的。遵循reduce方法并修改输出 |
scope |
document | 指定在映射中可访问的全局变量,减少和确定函数。 |
jsMode |
boolean |
指定是否将中间数据转换为BSON格式,以执行映射和reduce函数。 If
If
|
verbose |
boolean |
指定是否在结果信息中包含计时信息。将verbose设置为true,以包含计时信息。 |
collation |
document |
可选的。 在指定排序时,locale字段是强制的;所有其他排序字段都是可选的。有关字段的描述,请参见Collation文档。 如果排序未指定,但是集合有默认的排序规则(请参阅db.createCollection()),该操作将使用指定的排序集。 |
详细文档:https://docs.mongodb.com/manual/core/master-slave/
1,基础搭建
①复制mongod程序到27000文件夹
②创建配置文件(1.config)
③创建db存储文件夹
2,配置master config
port=27000 bind_ip=192.168.1.150 dbpath=./db master=true
启动mongodb: ./mongod --config 1.config
3,配置slave config
port=27001 bind_ip=192.168.1.150 dbpath=./db slave=true source=192.168.1.150:27000
启动mongodb: ./mongod --config 1.config
4,其他配置项
only:可选的。 指定数据库的名称。 指定时,MongoDB将只复制指定的数据库。
master挂掉其中一个secondary变为master
arbiter:仲裁者没有数据集的副本,也不能成为主数据集。 副本组可能会有仲裁者在选举主要增加一票。 仲裁者总是恰好1选投票,从而让副本集有奇数表决权的成员
1,配置
port=27000 bind_ip=192.168.1.150 dbpath=./db replSet=test
27001、27002、27003配置文件差不多
2,启动服务
./mongod --config 1.config
3,随便链接一台mongodb(例如链接192.168.1.150:27000)
添加集群
rs.initiate()//初始化ReplicaSet集群 rs.config()//查看配置信息 rs.status()//查看状态 //向集群中添加members rs.add("192.168.1.150:27001") rs.add("192.168.1.150:27002") //添加仲裁 rs.addArb("192.168.1.150:27003")
1,配置
27000(mongos):
port=27000 bind_ip=192.168.1.150 configdb=192.168.1.150:27001
27001(config):
port=27001 bind_ip=192.168.1.150 dbpath=./db configsvr=true
启动: ./mongod --config 1.config
27002:
27003:
3,步骤
①开启config服务器
②开启mongos服务器
nuget:MongoDB.Driver
class Program { static void Main(string[] args) { // or use a connection string var client = new MongoClient("mongodb://192.168.1.150:27017"); var db = client.GetDatabase("test"); db.CreateCollection("aa"); } }