枚举MongoDB 中 $ 操作符

查询

1. 比较操作符

操作符 语法 说明
$eq { <field>: { $eq: <value> } } 匹配等于(=)指定值的文档
$gt { <field>: {$gt: <value>} } 匹配大于(>)指定值的文档
$gte { <field>: { $gte: <value> } } 匹配等于(>=)指定值的文档
$lt { <field>: { $lt: <value> } } 匹配等于(<)指定值的文档
$lte { <field>: { $lte: <value> } } 匹配等于(<=)指定值的文档
$ne { <field>: { $ne: <value> } } 匹配等于(≠)指定值的文档
$in { <field>: { $in: <list> } } 匹配数组中的任一值
$nin { <field>: { $nin: <list> } } 不匹配数组中的值

示例代码:

//查询age=20的文档:
db.person.find( { age: { $eq: 20 } } )
//相当于:
db.person.find( { age: 20 } )

//查询该集合中字段qty的值等于 5 或者 15 的文档:
db.inventory.find( { qty: { $in: [ 5, 15 ] } } )

2. 逻辑操作符

操作符 语法 说明
$or { $or: [ {<expression1>}, {<expression2>}, ... {<expressionN>} ] } 符合至少一个条件
$and { $and: [ {<expression1>}, {<expression2>} , ... {<expressionN>} ] } 符合所有条件
$not { field: { $not: { <operator-expression> } } } 不符合条件
$nor { $nor: [ {<expression1>}, {<expression2>}, ... {<expressionN>} ] } 不符合所有条件

示例代码:

//查询age<20或者address是beijing的文档:
db.person.find( { $or: [ { age: { $lt: 20 } }, { address: "beijing" } ] } )

//查询age不大于20的文档:
db.person.find( { age: { $not: { $gt: 20 } } } )

//查询age既不等于20,sex也不是男的文档:
db.person.find( { $nor: [ { age: 20 },{ sex: "男"} ] } )

3. 元素操作符

操作符 语法 说明
$exists { field: { $exists: <boolean> } } 查询存在指定字段的文档
$type `{ field: { $type: <BSON type number> <String alias> } }`

3.2版本添加alias别名,各种类型的Number及Alias如下

image.png

示例代码:

//查询存在phone字段的文档:
db.person.find( { phone: { $exists: true } } )

//假设存在这样一个集合:
{ "_id": 1, address: "2030 Martian Way", zipCode: "90698345"},
{ "_id": 2, address: "156 Lunar Place", zipCode: 43339374},
{ "_id": 3, address: "2324 Pluto Place", zipCode: NumberLong(3921412)},
{ "_id": 4, address: "55 Saturn Ring", zipCode: NumberInt(88602117)}
//查询该集合中zipCode字段的数据类型为String类型的文档:
db.addressBook.find( { "zipCode" : { $type : 2 } } );
db.addressBook.find( { "zipCode" : { $type : "string" } } );

4. 评估操作符Evaluation

操作符 语法 说明
$mod { field: { $mod: [ 除数, 余数 ] } } 取余条件查询
$regex { <field>: { $regex: /pattern/<options> } } 正则表达式查询
$options { <field>: { $regex: /pattern/, $options: '<options>' } } 为正则添加标志符
$where { <field>: { $where: <js code(return boolean)> } } js语法查询
$text { <field>: { $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } } } 文本索引查询

$text参数: $search —— 关键词 $language —— 语言,不支持中文! $caseSensitive —— 是否区分大小写,默认false $diacriticSensitive —— 是否区分读音,默认false

示例代码:

//查询符合条件的文档:
db.myCollection.find( { $where: "this.credits == this.debits" } );
db.myCollection.find( { $where: function() { return obj.credits == obj.debits; } } );

5. 数组操作符

操作符 语法 说明
$all { <field>: { $all: [<value1>, <value2>...] } } 匹配文档的数组字段中包含所有指定元素的文档
$elemMatch { <field>: { $elemMatch: { <query1>, <query2>, ... } } } 匹配内嵌文档或数组中的部分field
$size { field: { $size: <number> } 匹配数组长度为指定大小的文档

示例代码:

//查询articles集合中tags字段(是个数组)包含“ssl”和“security”的文档(包含,但并不是全部等于)
db.articles.find( { tags: { $all: [ [ "ssl", "security" ] ] } } )

//假设现有集合:
{ _id: 1, results: [ 82, 85, 88 ] }
{ _id: 2, results: [ 75, 88, 89 ] }
//查询results数组中含有区间[80,85)元素的文档(结果为第一条):
db.scores.find( { results: { $elemMatch: { $gte: 80, $lt: 85 } } })

//查询已经集齐了5张福卡的文档:
db.person.find({card:{$size:5}})

6. 投影操作符

投影(project)的功能可以与SQL中的select类比,满足此条件的文档只返回包含指定字段的结果集。 位置$符来匹配查询条件的第一个文档,$一般伴随着其他条件来限定数组元素的获取。 比如这个条件 { semester: 1, grades: { $gte: 85 } }, { "grades.$": 1 } 就是在满足前面两个条件下,只获取grades数组第一个匹配的元素。 $elemMatch如上述的应用一样返回符合匹配的第一个元素。

操作符 说明
$(projection) 查询数组中首个匹配条件的元素,相当于findOne()方法
$elemMatch 用于数组或内嵌文档中的元素匹配(子元素匹配),只会返回匹配的第一个元素
$slcie 在查询中将数组进行切片(类似于分页)

示例代码:

//假设现有如下集合students:
{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] }
{ "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] }
{ "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }
{ "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] }
{ "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] }
{ "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }
//查询semester=1,并且grades中符合大于等于85的元素的第一个元素:
db.students.find( { semester: 1, grades: { $gte: 85 } },{ "grades.$": 1 } )
//返回如下结果:
{ "_id" : 1, "grades" : [ 87 ] }{ "_id" : 2, "grades" : [ 90 ] }{ "_id" : 3, "grades" : [ 85 ] }

//假设现有如下集合:
{
  _id: 1,
  zipcode: "63109",
  students: [
    { name: "john", school: 102, age: 10 },
    { name: "jess", school: 102, age: 11 },
    { name: "jeff", school: 108, age: 15 }
  ]
},
{
  _id: 2,
  zipcode: "63110",
  students: [
    { name: "ajax", school: 100, age: 7 },
    { name: "achilles", school: 100, age: 8 },
  ]
},
{
  _id: 3,
  zipcode: "63109",
  students: [
    { name: "ajax", school: 100, age: 7 },
    { name: "achilles", school: 100, age: 8 },
  ]
}
//查询zipcode为63109并且students数组中school=102的文档:
db.schools.find( { zipcode: "63109" },{ students: { $elemMatch: { school: 102 } } } )
//返回如下结果:
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }{ "_id" : 3 }

//(1)查询结果中,对于comments数组的元素只显示前5个:
db.posts.find( {}, { comments: { $slice: 5 } } )
//(2)查询结果中,对于comments数组的元素只显示后5个:
db.posts.find( {}, { comments: { $slice: -5 } } )
//(3)查询结果中,对于comments数组的元素跳过(skip)前20个,并只显示(limit)10个元素(即21-30):
db.posts.find( {}, { comments: { $slice: [ 20, 10 ] } } )
//(4)同理,跳过后20个,并显示10个:
db.posts.find( {}, { comments: { $slice: [ -20, 10 ] } } )

更新

1. 字段操作符

操作符 语法 说明
$inc { $inc: {<field>: <number>} } 将文档中的某个field对应的value自增/减某个数字amount
$mul { $mul: {<field>: <number>} } 将文档中的某个field对于的value做乘法操作
$rename { $rename: {<field>: <newName>} } 重命名文档中的指定字段的名
$setOnInsert db.collection.update( <query>, { $setOnInsert: { <field1>: <value1>, ... } }, { upsert: true }) 配合upsert操作,在作为insert时可以为新文档扩展更多的field
$set { $set: { <field>: <value> } } 更新文档中的某一个字段,而不是全部替换
$unset { $unset: { <field>: "" } } 删除文档中的指定字段,若字段不存在则不操作
$min { $min: { <field>: <value> } } 将文档中的某字段与指定值作比较,如果原值小于指定值,则不更新;若大于指定值,则更新
$max { $max: { <field>: <value>, ... } } $min功能相反
$currentDate { $currentDate: { <field>: <dateType> } } 设置指定字段为当前时间

示例代码:

//将_id为1的文档的age字段在原来的基础上+1:
db.person.update( { _id: 1 }, { $inc: { age: 1} })

//将_id为1的文档的price值乘以1.25并更新:
db.products.update( { _id: 1 }, { $mul: { price: 1.25 } })

//将_id为1的文档的nickname字段重命名为alias,cell字段重命名为mobile
db.person.update( { _id: 1 }, { $rename: { 'nickname': 'alias', 'cell': 'mobile' } } )

//将_id为1的文档的item字段更改为apple,并插入新字段defaultQty,值为100
db.products.update(
  { _id: 1 },
  {
    $set: { item: "apple" },
    $setOnInsert: { defaultQty: 100 }
  },
  { upsert: true }
)

//假设现有文档:
{_id:1,name:"zhangsan",sex:"男"}
//如果这样写:
db.person.update({_id:1},{sex:"女"});
//则更改之后的结果是酱的:
{_id:1,sex:"女"}
//若只想更改sex字段,可以这样写:
db.person.update({_id:1},{$set:{sex:"女"}});

//删除_id为1的文档的name字段
db.person.update( { _id: 1}, { $unset: { name:"" } })

//假设现有文档:
{ _id: 1, highScore: 800, lowScore: 200 }
//执行:
db.scores.update( { _id: 1 }, { $min: { lowScore: 150 } } )
//执行结果:
{ _id: 1, highScore: 800, lowScore: 150 }

//给登录用户更新lastLogin,类型为时间戳(timestamp)
db.person.update( { _id: 1 }, { $currentDate: { "lastLogin": { $type: "timestamp" } } })

2. 数组操作符

操作符 语法 说明
$(update) { "<array>.$": value } 更新
$addToSet { $addToSet: { <field>: <value> } } 用于添加一个元素到array中,一般用于update
$pop { $pop: { <field>: <number> } } 从尾部开始删除数组中一个元素
$pullAll { $pullAll: { <field>: [ <value1>, <value2> ... ] } } 删除数组或内嵌文档字段中所有指定的元素
$pull `{ $pull: { <field>: <value condition> } }`
$push { $push: { <field>: <value> } } 往数组尾部追加指定的元素,若文档中数组不存在,则创建并添加指定元素
$each `{ $addToSet $push: { <field>: { $each: [ <value1>, <value2> ... ] } } }`
$sort { $push: {...,$sort: { <field: 1/-1> }} } 给文档中的指定数组元素排序,1是升序,-1是降序,配合$push使用
$position { $push: {...,$position: <num> } 配合$push使用,往数组元素中的指定位置插入

示例代码:

//假设现有文档:
{ _id: 1, letters: ["a", "b"] }
//执行:
db.test.update({_id:1},{$addToSet:{letters:"c"}})
//结果:
{ "_id" : 1, "letters" : [ "a", "b", "c" ] }
//执行:
db.test.update({_id:1},{$addToSet:{letters:["d","e"]}})
//结果:
{ "_id" : 1, "letters" : [ "a", "b", "c", [ "d", "e" ] ] }
//注意,若想让添加的多个元素分开成单个元素的效果,请参考$each的使用方法

//删除_id为1的文档中 letters数组 的 第一个数据:
db.test.update({_id:1},{$pop:{letters:-1}});

//假设现有文档:
{ _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] }
//执行:
db.test.update( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } )
//结果:
{ "_id" : 1, "scores" : [ 2, 1 ] }

//假设现有文档:
{ _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] }
//执行:
db.test.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )
//结果:
{ _id: 1, votes: [ 3, 5 ] }

db.students.update( { _id: 1 }, { $push: { scores: 89 } })

db.students.update(
   { _id: 1 },
   {
     $push: {
       quizzes: {
         $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ],
         $sort: { score: 1 }
       }
     }
   }
)
WRITTEN BY

lidong

鄂ICP备20003892号Copyright © 2017-2023 leedong.cn

ABOUT ME

Hello,这里是「我的心情永不立冬」
一个想到什么就做什么的个人站点,所有内容纯主观、有偏见