前置知识

find 语法

格式:db.COLLECTION_NAME.find(query, projection)

参数说明:

  • query:可选,使用查询操作符指定的查询条件。
  • projection:可选,使用投影操作符指定返回的键。如果要在查询时返回文档中所有键值,只需省略该参数即可(默认为省略)。

文档查询条件的构造可以参考下表所示。

操作格式范例
等于{<key>:<value>}db.col.find({"by":"x"})
小于{<key>:{$lt:<value>}}db.col.find("likes":{$lt:50}})
小于等于{<key>:{$lte:<value>}}db.col.find(("likes":{$lte:50}})
大于{<key>:{$gt:<value>}}db.col.find("likes":{$gt:50}})
大于等于{<key>:{$gte:<value>}}db.col.find("likes":{$gte:50}})
不等于{<key>:{$ne:<value>}}db.col.find("likes":{$ne:50}})
包含{<key>:{$in:[<value1>,...,<valueN>]}}db.col.find("likes":{$in:[2,3,4]}})
不包含{<key>:{$nin:[<value1>,...,<valueN>]}}db.col.find("likes":{$nin:[2,3,4]}})
{<key>:{$not:query}}db.col.find("likes":{$not:{$lt:50}}})

解释 非where not likes < 50

aggregate() 聚合

db.COLLECTION_NAME.aggregate()

  • $sum:
  • $avg
  • $min
  • $max
  • $first
  • $last:根据资源文档的排序获取最后一个文档数据

    db.mycol.aggregate([{$group:{_id:"$by_user", last_url:{$last:"$url"}}}])

可以使用 limit、skip、sort 限制返回结果数量、忽略一定数量结果、执行排序处理。

数据准备

创建实验数据集合

itmes 集合,保存订单信息。

db
db.createCollection("items")

image.png

插入文档数据

pnumber:商品编号
quantity:商品数量
price:商品价格

db.items.insertMany([
{"quantity":2,"price":5.0, "pnumber":"p003"},
{"quantity":2,"price":8.0, "pnumber":"p002"},
{"quantity":1,"price":4.0, "pnumber":"p002"},
{"quantity":2,"price":4.0, "pnumber":"p001"},
{"quantity":4,"price":10.0, "pnumber":"p003"},
{"quantity":10,"price":20.0, "pnumber":"p001"},
{"quantity":10,"price":20.0, "pnumber":"p003"},
{"quantity":5,"price":10.0, "pnumber":"p002"}
])

image.png

格式化显示文档

db.items.find().pretty()

image.png

文档查询操作

(1) countDocuments()

统计集合中总共多少文档

db.items.countDocuments({})

image.png

(2) distinct()

使用 distinct 命令查询指定键的所有不同值,使用时必须指定集合和键。

例如,对 price 键使用 distinct,会得到所有不同的价格。
db.runCommand({"distinct":"items","key":"price"})

image.png

(3) 单条件查询

例如,查询价格大于5的商品数据,大于使用 gt 操作符,操作符前面要带上 $ 符号。
db.items.find({price:{$gt:5}})

image.png

(4) 多条件查询

多条件组合查询,各个条件之间默认是 AND 关系。

例如,查询 quantity 为 10 且价格大于等于 5 的商品数据。
db.items.find({quantity:10,price:{$gte:5}})

image.png

也可以使用 $or 来进行多条件查询,语法格式如下:

db.collectionName.find(
{
    $or:[
      {key:value},
      {key:value}
    ]
})
例如,查询 quantity 为 10 或价格大于等于 5 的商品数据。
db.items.find({$or:[{quantity:10},{price:{$gte:5}}]})

image.png

还可以将 AND 和 OR 联合使用。

例如,查询 pnumber 为"p003"且 quantity 为 10 或价格大于等于 5 的商品数据
db.items.find({
    pnumber:"p003",
    $or:[
        {quantity:10},
        {price:{$gte:5}}
    ]
})

image.png

(5) $in 查询

例如,要找出 quantity为2、4、5的文档。
db.items.find({quantity:{$in:[2,4,5]}})

image.png
$nin 将返回与数组中所有条件都不匹配的文档。

要是想返回所有 quantity 不是2、4、5 的文档,就可以用:
db.items.find({quantity:{$nin:[2,4,5]}})

image.png

说明

值得注意的是,$in能对单个键做OR查询,但是要对多个键做查询就得使用$or。
使用普通的AND型查询时,总是希望尽可能用最少的条件来限定结果的范围。OR型查询正好相反,第一个条件应该尽可能匹配更多的文档,这样才是最为高效的。
$or 操作符在任何情况下都会正常工作,而如果查询优化器可以更高效地处理$in,则应该优先选择使用$in操作符。

(6) $not 查询

以取模运算符 $mod 为例,$mod 会将查询的值除以第一个给定值,若余数等于第二个给定值则匹配成功。

例如,要查询 quantity 值为奇数的文档。
db.items.find({quantity:{$mod:[2,1]}})

image.png

要查询 quantity 值为偶数的文档,添加 $not
db.items.find({quantity:{$not:{$mod:[2,1]}}})

image.png

(7) null 查询

null 不仅会匹配值为 null 的文档,还会匹配不包含这个键的文档(即返回缺少这个键的所有文档)。

如果仅想匹配键值为 null 的文档,则既要检查该键的值是否为null,还要通过 $exists 条件判定键值已存在。

db.item.find({price:{$in:[null],$exists:true}})

image.png
由于没有$eq(等于)操作符,所以这条查询语句看上去麻烦,但是与只有一个元素的$in效果一样。

(8) aggregate 聚合查询

使用group可以执行更复杂的聚合。先选定分组所依据的键,而后MongoDB就会将集合依据选定键的不同值分成若干组。然后可以对每一个分组内的文档进行聚合,最后可以得到一个结果文档。

例如,统计订单中所有商品的数量,即统计quantity的总和。
db.items.aggregate([{
    $group:{_id:null,total:{$sum:"$quantity"}}
}])

image.png

例如,通过产品类型来进行分组,然后在统计卖出的数量。
db.items.aggregate([{
$group:{_id:"$pnumber",total:{$sum:"$quantity"}}
}])

image.png

例如,通过相同的产品类型来进行分组,然后查询相同产品类型中卖出最多的订单详情。
db.items.aggregate([{
$group:{_id:"$pnumber",max:{$max:"$quantity"}}
}])

image.png

例如,通过相同的产品类型来进行分组,然后查询每个订单详情相同产品类型卖出的平均价格。
db.items.aggregate([{
$group:{_id:"$pnumber",price:{$avg:"$price"}}
}])

image.png

(9) 管道的使用

例如,希望先通过相同的产品类型来进行分组,统计出各个产品的数量,然后再获取最大的数量,可以使用下面的命令。
db.items.aggregate([
{
    $group:{_id:"$pnumber",total:{$sum:"$quantity"}}
},
{
    $group:{_id:null, max:{$max:"$total"}}
}
])

image.png

(10) 查询选项

1. limit

限制返回结果

db.items.find().limit(3)

image.png

2. skip

丢弃结果集中的前n个文档,将剩余文档作为结果返回。在“普通”查询中,如果需要跳过大量的数据,那么这个操作符的效率会很低,因为它必须要先匹配到所有需要跳过的文档,然后再将这些文档丢弃。

例如,跳过前3个结果文档,可以使用如下命令。
db.items.find().skip(3)

image.png

3. sort

接受一个对象作为参数,该对象是一组键/值对。

  • 键对应文档的键名
  • 值代表排序的方向,排序方向可以是1(升序)或者-1(降序)
  • 如果指定了多个键,则按照这些键被指定的顺序逐个排序。
例如,要按照pnumber升序以及 price降序排序,可以使用下面的命令。
db.items.find().sort({pnumber:1, price:-1})

image.png

4. 分页

当点击“下一页”希望看到更多的结果时,可以通过skip非常简单地实现,只需要略过前3个结果即可(因为前3个已经在第一页显示了)

db.items.find().limit(3).skip(3).sort({price:-1})

image.png


pipiimmortal
13 声望0 粉丝