查询语法
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()
未格式化
格式化后显示:
格式化后显示
案例
新建客户文档,字段较多, 说明下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的客户,并只输出姓名和年龄:
查询年龄大于25的客户,并只输出姓名和年龄
- 查询年龄大于25并且标签是男性的客户,并只输出姓名,年龄,标签:
查询年龄大于25并且标签是男性的客户,并只输出姓名,年龄,标签
- 查询地址都是Los Angeles的客户,只输出姓名,地址:
db.consumer.find(
{"orders":
{$elemMatch:
{"product":
{$elemMatch:{"name":"MongoDB从入门到放弃"}}
}
}
},
{name:1,orders:1}
)
查询买了“MongoDB从入门到放弃”书的客户:
查询买了“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分别使用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