mongodb 查询

find

find 方法来进行查询。查询就是返回集合中文档的一个子集,子集的范围从 0 个文档到整个集合。要返回哪些文档由 find 的第一个参数决定,该参数是一个用于指定查询条件的文档。

空的查询文档({})会匹配集合中的所有内容。如果 find 没有给定查询文档,则默认为 {}

可以在查询文档中加入多个键–值对,以将多个查询条件组合在一起,这样的查询条件会被解释为“条件 1 AND 条件 2 AND...AND 条件 N ”

db.movies.find()
db.movies.find({"title": "aaa"})
db.movies.find({"title": "aaa", "age": 20})

有时候并不需要返回文档中的所有键–值对。遇到这种情况时,可以通过find(或者 findOne)的第二个参数来指定需要的键。这样做既可以节省网络传输的数据量,也可以减少客户端解码文档的时间和内存消耗。

db.movies.find({"title": "aaa", "age": 20}, {"title": 1, "age": 1});
db.movies.find({"title": "aaa", "age": 20}, {"age": 0});

 

查询条件

比较运算符

"$lt"、"$lte"、"$gt" 和 "$gte" 都属于比较运算符,分别对应 <、<=、> 和>=。可以将它们组合使用以查找一个范围内的值。

db.movies.find({"age": {"$gte": 18, "$lte": 30}})

 

OR查询

有两种方式可以进行 OR 查询。"$in" 可以用来查询一个键的多个值。"$or" 则更通用一些,可以在多个键中查询任意的给定值。

db.movies.find({"age": {"$in": [18, 20, "30"]}})
db.movies.find({"age": {"$nin": [18, 20, "30"]}})
db.movies.find({"$or": [{"age": 18}, {"age": 20}]})
db.movies.find({"$or": [{"age": {"$in": [18]}}, {"age": 20}]})

虽然总是可以使用 "$or",但只要有可能就应该使用 "$in",因为查询优化器可以更高效地对其进行处理。

 

$not

"$not" 是一个元条件运算符:可以用于任何其他条件之上。以取模运算符"$mod" 为例,"$mod" 会将查询的值除以第一个给定值,如果余数等于第二个给定值,则匹配成功:

db.movies.find({"_id": {"$mod": [5, 1]}})
db.movies.find({"_id": {"$not": {"$mod": [5, 1]}}})

  

特定类型的查询

null

null 的行为有一些特别。它可以与自身匹配

不过,null 同样会匹配“不存在”这个条件。因此,对一个键进行 null 值的请求还会返回缺少这个键的所有文档

如果仅想匹配键值为 null 的文档,则需要检查该键的值是否为 null,并且通过 "$exists" 条件确认该键已存在。

db.movies.find({"age": null})
db.movies.find({"age": {"$eq": null, "$exists": true}})

 

正则表达式

 "$regex" 可以在查询中为字符串的模式匹配提供正则表达式功能。

db.movies.find({"title": {"$regex": /aaa/i}})

MongoDB 会使用 Perl 兼容的正则表达式(PCRE)库来对正则表达式进行匹配。任何 PCRE 支持的正则表达式语法都能被 MongoDB 接受。在查询中使用正则表达式之前,最好先在 JavaScript shell 中检查一下语法,这样可以确保匹配与预想的一致。

 

查询数组

db.food.insertOne({"fruit": ["apple", "banana", "peach"]})
// 查询数组元素的方式与查询标量值相同。
db.food.find({"fruit": "banana"})
db.food.insertOne({"_id": 1, "fruit": ["apple", "banana", "peach"]})
db.food.insertOne({"_id": 2, "fruit": ["apple", "kumquat", "orange"]})
db.food.insertOne({"_id": 3, "fruit": ["cherry", "banana", "apple"]})
// 如果需要通过多个元素来匹配数组,那么可以使用 "$all"。可以使用 "$all" 查询来找到同时包含元素 "apple" 和 "banana" 的文档
db.food.find({fruit: {$all: ["apple", "banana"]}})
// 也可以使用整个数组进行精确匹配。不过,精确匹配无法匹配上元素丢失或多余的文档。
db.food.find({"fruit": ["apple", "banana", "peach"]})
// 如果想在数组中查询特定位置的元素,可以使用 key.index 语法来指定下标
db.food.find({"fruit.2": "peach"})
// "$size" 条件运算符对于查询数组来说非常有用,可以用它查询特定长度的数组
db.food.find({"fruit": {"$size": 3}})

// "$slice" 运算符可以返回一个数组键中元素的子集
// 假设现在有一个关于博客文章的文档,我们希望返回前 10 条评论
db.blog.posts.findOne({}, {"comments" : {"$slice" : 10}})
// 同样,如果想返回后 10 条评论,则可以使用 -10
db.blog.posts.findOne({}, {"comments" : {"$slice" : -10}})
// "$slice" 也可以指定偏移量和返回的元素数量来获取数组中间的结果
db.blog.posts.findOne({}, {"comments" : {"$slice" : [23, 10]}})
// 如果知道数组元素的下标,那么 "$slice" 非常有用。但有时我们希望返回与查询条件匹配的任意数组元素。这时可以使用 $ 运算符来返回匹配的元素
db.blog.posts.find({"comments.name" : "bob"}, {"comments.$" : 1})

 

查询内嵌文档

查询内嵌文档的方法有两种:查询整个文档或针对其单个键–值对进行查询。

查询整个内嵌文档的工作方式与普通查询相同

db.movies.find({
    "b2":
        {
            "name": "bbb",
            "rating": 4.3
        }
})

可以使用点表示法对内嵌文档的键进行查询:

db.movies.find({"b2.name": "bbb"})

"$elemMatch" 允许你将限定条件进行“分组”。仅当需要对一个内嵌文档的多个键进行操作时才会用到它。

db.movies.find({"b2": {"$elemMatch": {"name": "aaa", "rating": {"$gte": 2}}}})

 

参考: MongoDB权威指南(第3版)第 4 章 查询

 

posted @ 2022-01-29 16:46  草木物语  阅读(142)  评论(0)    收藏  举报