Note
-
MQL语法:
{<field>: {<operator>: <value>} }
-
聚合语法:
{<operator>: {<field>: <value>} }
基本查询运算符
db.collection_name.find()
比较运算符
-
常用运算符:
运算符 含义 $gt 大于 $lt 小于 $gte 大于等于 $lte 小于等于 $eq 匹配等于指定值的值 $ne 匹配所有不等于指定值的值。 -
语法格式:
{ "<field>": {"<operator>":<value>} }
-
Eg: sample_training.zips集合中有多少文档在pop字段中人数少于1000?
db.zips.find({ "pop" : { $lt: 1000 } } ).count()
-
查找birth year在1988和1999之间的文档(不含边界)
db.collection_name.find({ "birth year" : { $gt: 1998, $lt: 1998 } } );
// value1 < field < value
-
查找 triptime 小于或等于 30 秒且 type 不是 Subscriber 的所有文档:
-
db.trips.find({ "triptime": { "$lte" : 30 }, "type": { "$ne": "Subscriber" } }).pretty()
-
逻辑运算符
-
常用运算符:
运算符 含义 $and 匹配A 和 B的所有文档 $or 匹配A 或 B的所有文档 $nor 返回过滤掉查询条件的所有文档 $not 返回与查询不匹配的所有文档 -
语法格式:Eg:
-
db.collection_name.find({ "$or": [ { "$or" :[ { },{ }] }]})
-
-
$and Eg: inspections数据集中有多少家的result为A且sector为B?
-
db.inspections.find({"$and":[{"result":"A"},{"sector":"B"}]}).count() 或者 db.inspections.find({"result":"A","sector":"B" }).count()
-
-
$or Eg: 查找飞机 A 或 B 在 C 机场起飞或降落的所有文件:
-
db.routes.find({ "$and": [ { "$or" :[ { "dst_airport": "C" }, { "src_airport": "C" } ] }, { "$or" :[ { "airplane": "A" }, { "airplane": "B" } ] } ]}).pretty()
-
-
$nor Eg: 查询name不是Bob,age不是20的文档:
db.test.find( { $nor:[ { "name‘’: "Bob"}, {age: 3} ] } )
$expr
-
语法格式:
{ $expr: { <expression> } }
-
作用:
-
表示何时使用运算符
-
表示正在查看该字段的值,而不是字段本身
-
我们必须使用\(expr运算符来比较每个文档中的两个字段值。使用\)expr运算符是我们必须为比较运算符使用聚合语法的原因。
-
无需单独指定每个字段的值
-
-
Eg1: 我们正在比较同一文档中两个字段的值,以查看它们是否相等,使用\(访问字段值,以及使用我们在课程中看到的\)eq运算符的聚合语法。
db.companies.find({ "$expr": { "$eq": [ "$permalink", "$twitter_username" ]}}).count()
-
Eg2:
-
// 查找行程在同一车站开始和结束的所有文档:: db.trips.find({ "$expr": { "$eq": [ "$end station id", "$start station id"] } }).count() // 查找行程持续时间超过 1200 秒且在同一站点开始和结束的所有文档: db.trips.find({ "$expr": { "$and": [ { "$gt": [ "$tripduration", 1200 ]}, { "$eq": [ "$end station id", "$start station id" ]} ]}}).count()
-
-
Eg3: 员工>年份
-
db.companies.find( { "$expr": { "$gt": [ "$number_of_employees", "$founded_year" ] }}).count()
-
数组运算符
-
$push
- 作用
- 把 字段 转换为 数组字段
- 向数组添加元素
- 作用
-
$size
-
作用
- 返回指定数组字段恰好是给定长度的所有文档
-
Eg:
-
// 查找包含正好 20 个 便利设施的所有文档,其中包括 查询数组 中列出的所有便利设施: db.listingsAndReviews.find({ "amenities": { "$size": 20, // 元素个数为20的文档 "$all": [ "Internet", "Wifi", "Kitchen", "Heating", "Family/kid friendly", "Washer", "Dryer", "Essentials", "Shampoo", "Hangers", "Hair dryer", "Iron", "Laptop friendly workspace" ] } }).pretty() // 可以使用$size操作符来只选择评论字段中恰好有50 个元素的文档 wrong : db.listingsAndReviews.find({ "reviews":{ "$eq": 50 }}).count() right : db.listingsAndReviews.find({ "reviews": {"$size": 50}}).count()
-
-
-
$all
-
作用
- 返回在指定集合中至少包含这些指定元素的所有文档
-
Eg:
-
// return all listings that have "A", "B"as part of their amenities, and at least 2 C in the abc collection? db.abc.find( { "amenities": { "$all": [ "A", "B" ] }, "C": { "$gte": 2 } } ).pretty()
-
-
数组运算符和投影
-
为find()查询方法增加一个投影, 作用:只查看感兴趣的字段
-
语法:
db.<collection_name>.find({ <query> }, {<projection> })
- 1 指定要查看的字段 0指定不想查看的字段
- Note:但是在单个投影查询中不能同时使用1和0
- 除了
{"_id":0,<field>:1}
,因为_id
默认存在
- 除了
-
Eg1: 查找包含正好 20 个 便利设施的 所有文档,其中包括查询数组中列出的所有便利设施,并显示它们的价格 和 地址:
-
db.listingsAndReviews.find({ "amenities": { "$size": 20, "$all": [ "Internet", "Wifi", "Kitchen", "Heating", "Family/kid friendly", "Washer", "Dryer", "Essentials", "Shampoo", "Hangers", "Hair dryer", "Iron", "Laptop friendly workspace" ] } }, {"price": 1, "address": 1}).pretty()
-
-
Eg2: 查找所有将 Wifi 作为便利设施之一的 文档,只在结果光标中包含价格 和 地址 :
-
db.listingsAndReviews.find({ "amenities": "Wifi" }, { "price": 1, "address": 1, "_id": 0 }).pretty()
-
$elemMatch
-
作用:用
$elemMatch
可以再内嵌/含数组文档中数据过多时进行精确查找,避免数据的不准确。该操作符可将一组条件限定到数组中单条文档的匹配上 -
Eg1: 查找 431 班学生在任何类型的作业中获得高于 85 分的 所有文件: scores是一个数组
-
db.grades.find({ "class_id": 431 }, { "scores": { "$elemMatch": { "score": { "$gt": 85 } } }}).pretty()
-
-
Eg2: 比如有一组数据 john几门课的成绩为1,2,3,bob几门课的成绩为3,4,5。我们想查找john哪门课成绩为3
-
db.grades.find({"class.name":"john", "class.score":9}); //这样查找出来的数据会有john的全部成绩和bob成绩为3的课程。 VS db.grades.find({"class":{"$elemMatch":{"name":"joe", "score":3}}}); // 这样查找出来才正确
-
参考:https://blog.csdn.net/weixin_49485080/article/details/117651217?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163819938216780271572022%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163819938216780271572022&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-4-117651217.first_rank_v2_pc_rank_v29&utm_term=%24elemMatch&spm=1018.2226.3001.4187
-
-
Eg3: sample_training.companies集合中有多少家公司在西雅图市Seattle设有offices?offices是一个数组 里面有不同的字段和值,比如city:Seattle等
db.companies.find({"offices":{"$elemMatch":{"city":"Seattle"}}}).count();
数组运算符和子文档
-
比如一个A数组下有a, b,c 元素,我们需要反问b元素,则需表示为:
A.b
。 -
Eg1:
-
db.companies.find({ "relationships.0.person.first_name": "Mark", "relationships.0.title": { "$regex": "CEO" } }, { "name": 1 }).count() // $regex 操作符来设置匹配字符串的正则表达式.
-
-
Eg2:
-
db.companies.find({ "relationships.0.person.last_name": "Zuckerberg" }, { "name": 1 }).pretty()
-
-
Eg3: 在纽约市进行了多少次来自sample_training.inspections集合的检查?(address数组下有city zip number等)
db.inspections.find({"address.city":"NEW YORK"}).count()