$currentDate
db.getCollection('test').update({name:"shi"},{ $currentDate: {createdAt: true}}) 将时间类型的一个字段修改成当前时间
$push
db.students.update({ name: "joe" }, { $push: { scores: 1 } }) 在scores数组末尾添加一个元素,push只能添加一个
db.students.update(
{ name: "joe" },
{ $push: { scores: { $each: [ 90, 92, 85 ] } } }
) push添加多个需要使用$each
以前还有pushAll,现在已经被push+each代替了
$addToSet
db.inventory.update(
{ _id: 2 },
{ $addToSet: { tags: "camera" } }
) 向一个数组添加一个元素,前提是当前数组中并没有这个元素,如果有就不添加
db.inventory.update(
{ _id: 2 },
{ $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
)添加多个需要使用$each操作符
$expr, $setIsSubset 目标字段是查询参数的子集
> db.product.find()
{ "_id" : ObjectId("5d676f5f8b820718b993cd35"), "name" : 1, "vals" : [ "A", "B" ] }
{ "_id" : ObjectId("5d676fbc8b820718b993cd36"), "name" : 2, "vals" : [ "D", "C" ] }
{ "_id" : ObjectId("5d676fc98b820718b993cd37"), "name" : 3, "vals" : [ "A", "D" ] }
db.product.find( { $expr: { $setIsSubset: [ "$vals", ["A","B","D"] ] } } ) 查询要求cals是["A","B","D"]的子集
结果:
{ "_id" : ObjectId("5d676f5f8b820718b993cd35"), "name" : 1, "vals" : [ "A", "B" ] }
{ "_id" : ObjectId("5d676fc98b820718b993cd37"), "name" : 3, "vals" : [ "A", "D" ] }
$where 当一个查询比较复杂的时候,没有相应的运算符,可以使用function来完成一个复杂的查询条件
db.getCollection('apis').find({$where:function() { 这个查询也是实现了被查询文档的a字段的数组是[1,2,3,4]的子集
for (var num of this.a) {
if(![1,2,3,4].includes(num))return false
}
return true;
}})
$arrayElemAt 返回数组指定位置的元素
{ $arrayElemAt: [ [ 1, 2, 3 ], 0 ] } 返回
1
{ $arrayElemAt: [ [ 1, 2, 3 ], -2 ] } 返回
2
{ $arrayElemAt: [ [ 1, 2, 3 ], 15 ] }
数组越界无返回
{ "_id" : 1, "name" : "dave123", favorites: [ "chocolate", "cake", "butter", "apples" ] }
{ "_id" : 2, "name" : "li", favorites: [ "apples", "pudding", "pie" ] }
{ "_id" : 3, "name" : "ahn", favorites: [ "pears", "pecans", "chocolate", "cherries" ] }
{ "_id" : 4, "name" : "ty", favorites: [ "ice cream" ] }
db.users.aggregate([
{
$project:
{
name: 1,
first: { $arrayElemAt: [ "$favorites", 0 ] },
last: { $arrayElemAt: [ "$favorites", -1 ] }
}
}
])
{ "_id" : 1, "name" : "dave123", "first" : "chocolate", "last" : "apples" }
{ "_id" : 2, "name" : "li", "first" : "apples", "last" : "pie" }
{ "_id" : 3, "name" : "ahn", "first" : "pears", "last" : "cherries" }
{ "_id" : 4, "name" : "ty", "first" : "ice cream", "last" : "ice cream" }
$$root 引用当前管道处理的顶级文档,下面看例子
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
db.books.aggregate(
[
{ $group : { _id : "$author", books: { $push: "$$ROOT" } } }
]
)
先按照author分组两组,此处的$$root取出每一组的文档push到book中,结果如下:
{
"_id" : "Homer",
"books" :
[
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
]
}
{
"_id" : "Dante",
"books" :
[
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
]
}
$min,max 在aggregate中和update中是不一样的
在aggregate中的使用
{ "_id": 1, "quizzes": [ 10, 6, 7 ], "labs": [ 5, 8 ], "final": 80, "midterm": 75 }
{ "_id": 2, "quizzes": [ 9, 10 ], "labs": [ 8, 8 ], "final": 95, "midterm": 80 }
{ "_id": 3, "quizzes": [ 4, 5, 5 ], "labs": [ 6, 5 ], "final": 78, "midterm": 70 }
db.students.aggregate([
{ $project: { quizMin: { $min: "$quizzes"}, labMin: { $min: "$labs" }, examMin: { $min: [ "$final", "$midterm" ] } } }
])
{ "_id" : 1, "quizMin" : 6, "labMin" : 5, "examMin" : 75 }
{ "_id" : 2, "quizMin" : 9, "labMin" : 8, "examMin" : 80 }
{ "_id" : 3, "quizMin" : 4, "labMin" : 5, "examMin" : 70 }
max 和min的用法一样,只不过是好到数组中的最大
在update中使用:
{ _id: 1, highScore: 800, lowScore: 200 }
db.scores.update( { _id: 1 }, { $max: { highScore: 950 } } ) 在950和800中选出最大的跟新给highScore
{ _id: 1, highScore: 950, lowScore: 200 }
min和max的用法一样,选出最小的值跟新到指定字段。
$unset用户删除文档中的属性
删除一个直接的属性,删除文档中的quantity和instock属性,直接就没了,这两个属性
db.products.update(
{ sku: "unknown" },
{ $unset: { quantity: "", instock: "" } }
)
删除一个嵌套的属性
如果文档的quantity属性是一个object{a:1,b:2}
要删除quantity属性中的a属性,那么可以直接
db.products.update( { sku: "unknown" }, { $unset: { quantity.a: "", instock: "" } } )
删除数组中的属性
{
"_id" : 235399,
"casts" : {
"crew" : [
{
"_id" : 1186343,
"withBase" : true,
"department" : "Directing",
"job" : "Director",
"name" : "Connie Rasinski"
},
{
"_id" : 86342,
"withBase" : true
}
]
},
"likes" : 0,
"rating" : 0,
"rating_count" : 0,
"release_date" : "1955-11-11"
}
删除上面文档中crew数组中的每一个item的withBase属性可以调用
db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} )
$first
返回一个组的第一个指定的值,一般跟在sort之后
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") }
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
db.sales.aggregate(
[
{ $sort: { item: 1, date: 1 } },
{
$group:
{
_id: "$item",
firstSalesDate: { $first: "$date" }
}
}
]
)
{ "_id" : "xyz", "firstSalesDate" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : "jkl", "firstSalesDate" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : "abc", "firstSalesDate" : ISODate("2014-01-01T08:00:00Z") }
$concatArrays
连接两个数组,如果出现null或者字段缺失,那么连接后的结果也是null
{ "_id" : 1, instock: [ "chocolate" ], ordered: [ "butter", "apples" ] }
{ "_id" : 2, instock: [ "apples", "pudding", "pie" ] }
{ "_id" : 3, instock: [ "pears", "pecans"], ordered: [ "cherries" ] }
{ "_id" : 4, instock: [ "ice cream" ], ordered: [ ] }
db.warehouses.aggregate([
{ $project: { items: { $concatArrays: [ "$instock", "$ordered" ] } } }
])
{ "_id" : 1, "items" : [ "chocolate", "butter", "apples" ] }
{ "_id" : 2, "items" : null }
{ "_id" : 3, "items" : [ "pears", "pecans", "cherries" ] }
{ "_id" : 4, "items" : [ "ice cream" ] }
$concat
连接两个字符串,如果字段缺失或者null,则返回null
{ "_id" : 1, "item" : "ABC1", quarter: "13Q1", "description" : "product 1" }
{ "_id" : 2, "item" : "ABC2", quarter: "13Q4", "description" : "product 2" }
{ "_id" : 3, "item" : "XYZ1", quarter: "14Q2", "description" : null }
db.inventory.aggregate(
[
{ $project: { itemDescription: { $concat: [ "$item", " - ", "$description" ] } } }
]
)
{ "_id" : 1, "itemDescription" : "ABC1 - product 1" }
{ "_id" : 2, "itemDescription" : "ABC2 - product 2" }
{ "_id" : 3, "itemDescription" : null }
$ifnull
判断指定字段是否存在或者为null,如果是则替换为指定值,如果不是则直接返回
{ "_id" : 1, "item" : "abc1", description: "product 1", qty: 300 }
{ "_id" : 2, "item" : "abc2", description: null, qty: 200 }
{ "_id" : 3, "item" : "xyz1", qty: 250 }
db.inventory.aggregate(
[
{
$project: {
item: 1,
description: { $ifNull: [ "$description", "Unspecified" ] }
}
}
]
)
{ "_id" : 1, "item" : "abc1", "description" : "product 1" }
{ "_id" : 2, "item" : "abc2", "description" : "Unspecified" }
{ "_id" : 3, "item" : "xyz1", "description" : "Unspecified" }
$literal
不做任何的计算和转化,直接返回值
{ $literal: { $add: [ 2, 3 ] } } ==》 | { "$add" : [ 2, 3 ] } | |
{ $literal: { $literal: 1 } } ==》 | { "$literal" : 1 } |
eg1:
{ "_id" : 2, "item" : "xyz123", price: "1" }
{ "_id" : 3, "item" : "ijk123", price: "$1" }
db.records.aggregate( [ { $project: { costsOneDollar: { $eq: [ "$price", { $literal: "$1" } ] } } } ] )
{ "_id" : 1, "costsOneDollar" : false }
{ "_id" : 2, "costsOneDollar" : false }
{ "_id" : 3, "costsOneDollar" : true }
eg2:
{ "_id" : 1, "item" : "abc123", condition: "new" }
{ "_id" : 2, "item" : "xyz123", condition: "new" }
db.bids.aggregate( [
{ $project: { item: 1, startAt: { $literal: 1 } } }
] )
{ "_id" : 1, "item" : "abc123", "startAt" : 1 }
{ "_id" : 2, "item" : "xyz123", "startAt" : 1 }
$addFields
给文档添加一个字段或者修改已存在的字段的值
添加字段:
{
_id: 1,
student: "Maya",
homework: [ 10, 5, 10 ],
quiz: [ 10, 8 ],
extraCredit: 0
}
{
_id: 2,
student: "Ryan",
homework: [ 5, 6, 5 ],
quiz: [ 8, 8 ],
extraCredit: 8
}
db.scores.aggregate( [
{
$addFields: {
totalHomework: { $sum: "$homework" } ,
totalQuiz: { $sum: "$quiz" }
}
},
{
$addFields: { totalScore:
{ $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } }
}
] )
{
"_id" : 1,
"student" : "Maya",
"homework" : [ 10, 5, 10 ],
"quiz" : [ 10, 8 ],
"extraCredit" : 0,
"totalHomework" : 25,
"totalQuiz" : 18,
"totalScore" : 43
}
{
"_id" : 2,
"student" : "Ryan",
"homework" : [ 5, 6, 5 ],
"quiz" : [ 8, 8 ],
"extraCredit" : 8,
"totalHomework" : 16,
"totalQuiz" : 16,
"totalScore" : 40
}
添加内嵌文档的字段
{ _id: 1, type: "car", specs: { doors: 4, wheels: 4 } }
{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2 } }
{ _id: 3, type: "jet ski" }
db.vehicles.aggregate( [
{
$addFields: {
"specs.fuel_type": "unleaded"
}
}
] )
{ _id: 1, type: "car",
specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } }
{ _id: 2, type: "motorcycle",
specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } }
{ _id: 3, type: "jet ski",
specs: { fuel_type: "unleaded" } }
修改字段:
{ _id: 1, dogs: 10, cats: 15 }
db.animals.aggregate( [
{
$addFields: { "cats": 20 }
}
] )
{ _id: 1, dogs: 10, cats: 20 }
$arrayToObject
将一个array转化成一个object
被转换的array只支持两种形式
-
[ [ "item", "abc123"], [ "qty", 25 ] ] 转化成{ "item" : "abc123", "qty" : 25 }
- OR -
[ { "k": "item", "v": "abc123"}, { "k": "qty", "v": 25 } ] 转化成{ "item" : "abc123", "qty" : 25 }
例子:
{ "_id" : 2, "item" : "ABC2", dimensions: [ [ "l", 50 ], [ "w", 25 ], [ "uom", "cm" ] ] }
{ "_id" : 3, "item" : "ABC3", dimensions: [ [ "l", 25 ], [ "l", "cm" ], [ "l", 50 ] ] }
db.inventory.aggregate(
[
{
$project: {
item: 1,
dimensions: { $arrayToObject: "$dimensions" }
}
}
]
)
{ "_id" : 1, "item" : "ABC1", "dimensions" : { "l" : 25, "w" : 10, "uom" : "cm" } }
{ "_id" : 2, "item" : "ABC2", "dimensions" : { "l" : 50, "w" : 25, "uom" : "cm" } }
{ "_id" : 3, "item" : "ABC3", "dimensions" : { "l" : 50 } }
$objectToArray
将一个object转化成一个数组
|
|
|
|
{ "_id" : 1, "item" : "ABC1", dimensions: { l: 25, w: 10, uom: "cm" } }
{ "_id" : 2, "item" : "ABC2", dimensions: { l: 50, w: 25, uom: "cm" } }
{ "_id" : 3, "item" : "XYZ1", dimensions: { l: 70, w: 75, uom: "cm" } }
db.inventory.aggregate(
[
{
$project: {
item: 1,
dimensions: { $objectToArray: "$dimensions" }
}
}
]
)
{ "_id" : 1, "item" : "ABC1", "dimensions" : [ { "k" : "l", "v" : 25 }, { "k" : "w", "v" : 10 }, { "k" : "uom", "v" : "cm" } ] }
{ "_id" : 2, "item" : "ABC2", "dimensions" : [ { "k" : "l", "v" : 50 }, { "k" : "w", "v" : 25 }, { "k" : "uom", "v" : "cm" } ] }
{ "_id" : 3, "item" : "XYZ1", "dimensions" : [ { "k" : "l", "v" : 70 }, { "k" : "w", "v" : 75 }, { "k" : "uom", "v" : "cm" } ] }
$mergeObjects
将多个objects组合成一个
|
|
|
|
|
|
|
|
$replaceRoot
$replaceWith
这两个其实意思是一样的replaceWith是replaceRoot的别名,用指定文档替换当前文档
{ "_id" : 1, "name" : "Arlene", "age" : 34, "pets" : { "dogs" : 2, "cats" : 1 } }
{ "_id" : 2, "name" : "Sam", "age" : 41, "pets" : { "cats" : 1, "fish" : 3 } }
{ "_id" : 3, "name" : "Maria", "age" : 25 }
db.people.aggregate( [
{ $replaceRoot: { newRoot: { $mergeObjects: [ { dogs: 0, cats: 0, birds: 0, fish: 0 }, "$pets" ] }} }
] )
{ "dogs" : 2, "cats" : 1, "birds" : 0, "fish" : 0 }
{ "dogs" : 0, "cats" : 1, "birds" : 0, "fish" : 3 }
{ "dogs" : 0, "cats" : 0, "birds" : 0, "fish" : 0 }
$out
将结果插入指定的collection中
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 } { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 } { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 } { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 } { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
db.books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : "authors" } ] )
author collection: { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }