• 0

  • 0

MongoDB 之查询详解

1天前

查询就是获取存储在数据库中的数据。
在 MongoDB 中,查询通常针对一个集合来操作。查询可以指定查询条件,只返回匹配的文档;还可以指定投影项,只返回指定的字段,减少返回数据到客户端的网络流量。

1、MongoDB 查询文档使用 find() 方法

find() 方法以非结构化的方式来显示所有文档。

语法
MongoDB 查询数据的语法格式如下:

db.collection.find(query, projection)

参数说明:

query :可选,使用查询操作符指定查询条件。

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

如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式为:

db.col.find().pretty()

示例:

db.col.find().pretty()
{
“_id” : ObjectId(“56063f17ade2f21f36b03133”),
“title” : “aaa”,
“description” : “MongoDB 是一个 Nosql 数据库”,
“by” : “bb”,
“url” : “http://www.runoob.com”,
“tags” : [
“mongodb”,
“database”,
“NoSQL”
],
“likes” : 100
}

除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。
下面就来举例说明多表数如何关联的。

在关系数据库 MySQL 中我们可能需要设计 3 个表如客户表 customers、订单表 orders、商品表 products,其中 customers 表中的主键为 cust_id,products 表中的主键为prod_id,orders 表中主键 order_id,外键 cust_id 和 prod_id 分别与客户和产品关联,这就是在关系数据库中经常干的事情,整个结构如下图所示:

在这里插入图片描述

查询某个客户所订购的所有商品名称的 SQL 语句则为以下格式:

select tl.name,t3.prod_name from customer tl 
join orders t2 on tl.cust_id = t2.cust_id 
join products t3 on t2.prod_id = t3.prod_id;

在前面已经说过,mongodb中多表关联查询的话是没有join的;
在 MongoDB 中抛弃了这种关联的思路来设计表结构,在 MongoDB 中提倡的设计思路可能是建立一个客户表,在表中包含业务需要的尽可能多的数据信息,这样最终会产生一些冗余信息,但是在 NoSQL 的世界里是提倡这样做的。
与上面的业务需求相同,则最终插入的文档对象 document 结构如下所示:

db.customers.insert({
    
cust_id:123, 
name:"xiaoming", 
address:"china beijing", 
mobile:"999999", 

orders:[
{
    order_id:1, 
createTime:"2020-2-6", 

products: [
{
    prod_name: "surface Pro64G", prod_manufacture: "micosoft" }, 
{
    prod_name: "mini Apple", prod_manufacture: "Apple" } 
]},


{
    order_id:2, 
createTime:"2020-2-6", 
products: [ {
    prod_name: "xbox", prod_manufacture: "micosoft"},
{
    prod_name: "iphone",prod_manufacture: "Apple"}
] 
}

] 
});

这时使用mongodb查询某个客户下的所订购的商品信息的查询语句则为如下格式。

db.customers.find({
    cust_id:123},{
    name:1,orders:1}) 

上面从一个简单的业务需求对比了关系数据库和MongoDB的不同.

2.查询选择器

(1)查找全部:db.customers.find(),按照插入的顺序返回前 20 个文档,如果记录总数比 20 大,则我们可以通过命令“it”获取更多文档。

(2)精确匹配选择器

返回包含键值对 id:91的文档。

db.customers.find({id:1})

精确匹配选择器,但查询条件是要返回同时匹配键值对 name:“lisi”
且 age:20 的文档。

db.customers.find({name:“xiaoming”,age:101})

(3)比较运算符。

  • $lt 表示的是小于
  • $lte 表示的小于或等于
  • $gt 表示的是大于
  • $gte 表示的是大于或等于
  • $ne 表示不等于。单独使用$ne,它也不会利用索引的优势,反而会进行全表
    扫描。

示例:

db.customers.find({
    age:{
    $lt:102}})
db.customers.find({
    age:{
    $lte:102}})
db.customers.find({
    age:{
    $gt:109}})
db.customers.find({
    age:{
    $gte:109}})
db.customers.find({
    id:{
    $ne:1}})

(4)范围选择器

表示的是小于 120,大于或等于 119

db.customers.find({
    age:{
    $lt:120,$gte:119}})

(5)$in 和$nin

表示返回 key 的值在某些 value 范围内

db.customers.find({
    id:{
    $in:[1,2]}}) 

$nin 表示返回 key 的值不在某些 value 范围内,$nin 是一种比较低效的査询选择器,它会进行全表扫描,因此最好不要单独使用$nin

db.customers.find({
    id:{
    $nin:[1,2]}})

(6)逻辑运算

$or 表示或运算的选择器,主要用于对两个不同 key 对应的文档进行连接。

db.customers.find({
    $or:[{
    id:11},{
    age:119}]

$and 表示与运算的选择器,对于两个不同的 key,要同时满足条件。

db.customers.find({
    $and:[{
    id:11},{
    age:111}]})

(7) 嵌套查询

嵌套查询时匹配的 key 如果有多级嵌套深度,一级一级地用点号展开。假设系统中有如下所示的这样一种文档类型。

{
    
"_id" : Objectld("51e3e28e91fa05a27697ab55"), 
"id" : 1, "name" : "xiaohong",
"detail" : [{
     "sex" : "femle", "age" : 105}, 
{
     "address" : "china", "post" : 5}
]}

当查询 post 等于 5 的文档时,查询语句如下。

db.customers.find({
    'detail.1.post1':5}) 

匹配字符串中先取需要匹配的 key(detail),由于 detail 键对应的 value 为数组,detail.1 表示要取数组中第二个位置处的元素,又鉴于数组的元素也是个 BSON文档对象,我们可以通过 detail. 1.post 定位到需要匹配的键。

3.投影查询

上面介绍的查询选择器用来返回匹配的文档集,有时我们需要对返回的结果集作进一步的处理,如只需要返回指定的字段,此时就可以使用到投影查询。

db.customers. find({
    'detail.1.post':5}, {
    _id: 0, id:1, name:1}) 

此条语句执行的效果就是按照条件’detail.1.post’:5 来返回结果集,但是只选择 id 和 name 两个字段的值进行显示,同时过滤掉默认生成的_id 字段,总的来说,第一个{}内为查询选择器,第二个{}内为对前面返回的结果进行进一步的过滤,即投影查询。1 表示显示,0 表示不显示.

4.数组操作

假如有一个集合 DictGoodsAttribute 具有下面结构的数据。

{
    
"_id" : 4,
"AttributeName" : "material",
"AttributeValue":["牛仔","织锦","雷纺",帘丝"J,
"IsOptional" : 1 
} 
{
     
"_id" : 5, 
"AttributeName" : "version", 
"AttributeValue":["收腰型","修身型","直筒型","宽松型","其他"],
"IsOptional":1
}

(1)精确匹配数组值

我们可以通过简单的精确匹配得到某条记录,如以下语句所示。

db.DictGoodsAttribute.find({
    "AttributeValue":["收腰型","修身型","直筒型","
宽松型","其他"]}) 

(2)匹配数组中的一个元素值

假如数组有多个元素,只要这些元素中包含有这个值,就会返回这条文档,如下面语句所示。

db.DictGoodsAttribute. find({
     "AttributeValue":"收腰型"}) 

(3)匹配指定位置的元素值

db.DictGoodsAttribute. find ({
     "AttributeValue. 0":"收腰型"})

它表示数组中第 0 个位置的元素值为"收腰型"的记录才返回。

免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

0

相关文章推荐

未登录头像

暂无评论