查询语法

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

query

mongoDB 的query就好比MySQL中where后的内容。我们知道where后可以跟很多条件语句。MongoDB则是通过运算符进行复杂查询的。需要注意的是以下介绍的运算符不仅仅可以用在find中还可以用在更新,删除中的查询条件。下面将其中query的查询运算符进行介绍(只列出常用的类型,详细的可查看:你需要知道的9种Mongodb运算符):

逻辑运算符

名称

描述

语法

示例

$and

“and”条件对包含两个或多个表达式的数组执行逻辑“and”运算。它选择满足所有表达式条件的文档。

{ $and: [ { }, { }, ... , { } ] }

#查看商品文档中数量小于15并且价格等于10的记录

db.product.find( { $and: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

$or

“or”条件对包含两个或多个表达式的数组执行逻辑“or”运算。它选择至少有一个表达式为真的文档。

{ $or: [ { }, { }, ... , { } ] }.

#查看商品文档中数量小于15或者价格等于10的记录

db.product.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

$nor

使用一个或多个表达式对数组执行逻辑“nor”运算。它选择未通过查询表达式的文档。它与$or条件相反。

{ $nor: [ { }, { }, ... { } ] }

#查看商品文档中价格字段值不等于 3.99 美元,销售值不等于 true;


db.product.find( { $nor: [ { price: 3.99 }, { sale: true } ] } )

$not

它选择与查询表达式不匹配的文档。这包括不包含该字段的文档。

{ field: { $not: { } } }

#查询售价不小于(大于等于)3.99的记录

db.product.find( { price: { $not: { $lt: 3.99 } } } )

比较运算符

  • $gt: 如果请求的值“大于”查询中提供的值,则匹配;
  • $gte: 如果请求的值“大于或等于_”,则匹配查询中提供的值;
  • $lt: 如果请求的值是“小于”,则匹配查询中提供的值;
  • $lte: 如果请求的值是“小于或等于_”,则匹配查询中提供的值;

名称

描述

语法

示例

$eq

匹配等于给定值的记录

{field : { $eq: } }

db.inventory.find( { qty: { $eq: 20 } } )

$gt

如果请求的值“大于”查询中提供的值,则匹配;

{ field: { $gt: value } }

$gte

请求的值“大于或等于_”,则匹配查询中提供的值;

{ field: { $gte: value } }

$lt

请求的值是“小于”,则匹配查询中提供的值;

{ field: { $lt: value } }

$lte

请求的值是“小于或等于_”,则匹配查询中提供的值;

{ field: { $lte: value } }

$in

字段的值等于指定数组中的任何值。

{ field: { $in: [, , ... ] } }

db.collection.find({ "qty": { $in: [30, 15]}})

$nin

字段的值不等于指定数组中的任何值。

{ field: { $nin: [, , ... ] } }

元素运算符

元素查询运算符可以使用文档的字段来识别文档。元素运算符由$exist$type组成。

名称

描述

语法

示例

$exist

此运算符匹配具有指定字段的文档。该运算符有一个布尔值,可以是true或false。

如果指定为true,则匹配包含该字段的文档,包括字段值为空的文档。如果 是false,则查询仅返回不包含该字段的文档。

{ field: { $exists: } }

db.bagofmarbles.find( { red: { $exists: true } } )

$type

此运算符根据指定的字段类型匹配文档。当您拥有高度非结构化的数据或数据类型不可预测时,这很有用。这些字段类型是指定的 BSON 类型,可以通过类型号或别名来定义。

{ field: { $type: <BSON type> } }

db.addressBook.find({

"zipCode": {

$type: "string"

}

})

数组运算符

名称

描述

语法

示例

$all

$all运算符选择字段值是包含指定元素的数组的文档

{ : { $all: [ <value1> ,<value2> ... ] } }

db.inventory.find( { tags: { $all: [ "y2k", "trendy" ] } } )

$elemMatch

$elemMatch运算符匹配包含数组字段的文档,其中至少一个元素与所有指定的查询条件匹配;(经常用在数组为嵌套文档的场景)

{ : { $elemMatch: {<query1> ,<query2> , ... } } }

#数组包含至少一个大于或等于 90 且小于 95 的元素的文档

db.studentresults.find( { results: { $elemMatch: { $gte: 90, $lt: 95 } } })

$size

返回数组大小与参数中指定的元素数匹配的那些文档:

{ field: { $size: value } }

projection

projection指的是通过查询操作从文档中选择要返回的字段。可以使用Projection操作指定要返回的字段,而不是返回所有字段。这样可以减少查询的数据量和提高查询性能。

例如,以下查询将返回所有文档(默认情况下),但只包含title和author字段:

db.books.find({}, {title: 1, author: 1})

在上面的例子中,第二个参数是一个Projection操作,它指定只返回title和author字段,而不是返回所有字段。值为1表示要包含该字段,而值为0表示不要包含该字段。

pretty

如果需要格式化输出

db.mycollection.find().pretty()

MongoDB 各种复杂查询彻底弄明白_运算符

未格式化

格式化后显示:

MongoDB 各种复杂查询彻底弄明白_数组_02

格式化后显示

案例

新建客户文档,字段较多, 说明下json关键数组类型字段:

address:数组中放对象

"address": [
			{
         "streetAddress": "22 2nd Street",
         "city": "Los Angeles",
         "state": "LA",
         "postalCode": "10022"
     },
    {
            "streetAddress": "28 2nd Street",
            "city": "New York",
            "state": "NY",
            "postalCode": "10021"
     }
 ]

tag:数组中放string类型

"tag":["young","female"]

orders:数组中放对象对象中有嵌套数组})

[
        {
            "order_id": 4,
            "createTime": "2017-9-18",
            "product": [
                {
                    "name": "MongoDB从入门到放弃",
                    "describe": "xxx"
                },
								{
                    "name": "浪潮之巅",
                    "describe": "xxx"
                }
							]
        }
]

插入以下三条记录,为了展示json做了压缩:

db.consumer.insertOne({"cust_id":1,"name":"xiaoming","address":[{"streetAddress":"21 2nd Street","city":"New York","state":"NY","postalCode":"10021"}],"mobile":"1381111111","age":25,"tag":["IT","young","male"],"orders":[{"order_id":1,"createTime":"2013-7-13","product":[{"name":"surface Pro64G","describe":"xxx"},{"name":"mini Apple","describe":"xxx"}]},{"order_id":2,"createTime":"2013-8-12","product":[{"name":"xbox","describe":"xxx"},{"name":"iphone","describe":"xxx"}]}]})
db.consumer.insertOne({"cust_id":2,"name":"zhangshan","address":[{"streetAddress":"21 2nd Street","city":"Los Angeles","state":"LA","postalCode":"10022"},{"streetAddress":"21 2nd Street","city":"Washington","state":"WA","postalCode":"10023"}],"mobile":"1382222222","age":26,"tag":["young","female"],"orders":[{"order_id":3,"createTime":"2013-7-14","product":[{"name":"浪潮之巅","describe":"xxx"}]}]})
db.consumer.insertOne({"cust_id":3,"name":"lisi","address":[{"streetAddress":"22 2nd Street","city":"Los Angeles","state":"LA","postalCode":"10022"},{"streetAddress":"28 2nd Street","city":"New York","state":"NY","postalCode":"10021"}],"mobile":"1382222222","age":26,"tag":["young","female"],"orders":[{"order_id":4,"createTime":"2017-9-18","product":[{"name":"MongoDB从入门到放弃","describe":"xxx"},{"name":"浪潮之巅","describe":"xxx"}]}]})
  • 查询年龄大于25的客户,并只输出姓名和年龄:

MongoDB 各种复杂查询彻底弄明白_运算符_03

查询年龄大于25的客户,并只输出姓名和年龄

  • 查询年龄大于25并且标签是男性的客户,并只输出姓名,年龄,标签:

MongoDB 各种复杂查询彻底弄明白_数组_04

查询年龄大于25并且标签是男性的客户,并只输出姓名,年龄,标签


  • 查询地址都是Los Angeles的客户,只输出姓名,地址:
db.consumer.find(
{"orders":
	{$elemMatch:
		{"product":
			{$elemMatch:{"name":"MongoDB从入门到放弃"}}
		}
	}

},
{name:1,orders:1}
)

MongoDB 各种复杂查询彻底弄明白_字段_05

查询买了“MongoDB从入门到放弃”书的客户:

MongoDB 各种复杂查询彻底弄明白_运算符_06

查询买了“MongoDB从入门到放弃”书的客户

排序

在MongoDB中对结果进行排序,可使用sort()方法。该方法接受一个包含字段列表及其排序顺序的参数,要指定排序顺序,使用1和-1,1用于升序,-1用于降序。

语法如下:

db.COLLECTION_NAME.find().sort({KEY:1})

假如user文档中有如下数据

{
   
    "username": "user04",
    "createtime": ISODate("2020-09-01T15:38:24.773Z"),
    "status": NumberInt("1")
},
{
   
    "username": "user05",
    "createtime": ISODate("2020-09-01T15:38:52.02Z"),
    "status": NumberInt("2"),
    "activeStatus": NumberInt("1")
},
{
   
    "username": "user08",
    "createtime": ISODate("2020-09-01T16:04:17.762Z"),
    "status": NumberInt("1")
}

根据创建时间逆序查询用户表:

db.user.find().sort({createtime:-1})

MongoDB 各种复杂查询彻底弄明白_字段_07

分页

MongoDB分别使用limit(),skip() 来实现分页。其中

  • limit(): 取多少个文档
  • skip() : 跳过多少个文档
db.person.find().skip(n).limit(m)

db.comment.find().skip(3) 即查询comment集合中 跳过前三条的所有数据;

db.comment.limit(2).skip(3) 即查询 comment集合中 跳过前三行数据 ,显示后面的连续两条数据

需要注意的是无论skip在limit 之前还是之后都是先执行skip