mongoDB 文档查询

在关系型数据库中,可以实现基于表上各种各样的查询,以及通过投影来返回指定的列。对于NoSQL mongoDB而言,所有能够在单表上完成的查询,在mongoDB中也可以完全胜任。除此之外,由于mongoDB支持基于文档嵌套以及数组,因此mongoDB也可以实现基于嵌套文档和数组的查询。具体见下文描述。

预备热身
Linux下快速安装MongoDB
Windows平台下安装MongoDB
mongoDB 启动与停止
mongo shell连接到mongoDB及shell提示符下执行js脚本
mongoDB简介及关键特性
SQL与mongoDB对比及映射

一、查询语法

    db.collection.find( <query filter>, <projection> )
    db.collection.findOne()  //仅仅返回单个文档,相当于使用limit

    <query filter> 查询的过滤条件
    <projection>   投影,即哪些列需要返回
    对于查询的结果可以添加limits, skips, sort 等方式控制返回的结果集
    缺省情况下,在mongo shell中对于未使用将结果集返回给变量的情形下,仅返回前20条记录
    注:本文描述中有些地方使用到了文档的键值对,称为键和值,有些地方称为列,是一个概念

二、准备数据

    //演示环境
    db.version()
    3.2.9

    //插入演示数据
    db.users.insertMany(
      [
         {
           _id: 1,
           name: "sue",
           age: 19,
           type: 1,
           status: "P",
           favorites: { artist: "Picasso", food: "pizza" },
           finished: [ 17, 3 ],
           badges: [ "blue", "black" ],
           points: [
              { points: 85, bonus: 20 },
              { points: 85, bonus: 10 }
           ]
         },
         {
           _id: 2,
           name: "bob",
           age: 42,
           type: 1,
           status: "A",
           favorites: { artist: "Miro", food: "meringue" },
           finished: [ 11, 25 ],
           badges: [ "green" ],
           points: [
              { points: 85, bonus: 20 },
              { points: 64, bonus: 12 }
           ]
         },
         {
           _id: 3,
           name: "ahn",
           age: 22,
           type: 2,
           status: "A",
           favorites: { artist: "Cassatt", food: "cake" },
           finished: [ 6 ],
           badges: [ "blue", "red" ],
           points: [
              { points: 81, bonus: 8 },
              { points: 55, bonus: 20 }
           ]
         },
         {
           _id: 4,
           name: "xi",
           age: 34,         //Author : Leshami
           type: 2,         //Blog   : http://blog.csdn.net/leshami
           status: "D",
           favorites: { artist: "Chagall", food: "chocolate" },
           finished: [ 5, 11 ],
           badges: [ "red", "black" ],
           points: [
              { points: 53, bonus: 15 },
              { points: 51, bonus: 15 }
           ]
         },
         {
           _id: 5,
           name: "xyz",
           age: 23,
           type: 2,
           status: "D",
           favorites: { artist: "Noguchi", food: "nougat" },
           finished: [ 14, 6 ],
           badges: [ "orange" ],
           points: [
              { points: 71, bonus: 20 }
           ]
         },
         {
           _id: 6,
           name: "abc",
           age: 43,
           type: 1,
           status: "A",
           favorites: { food: "pizza", artist: "Picasso" },
           finished: [ 18, 12 ],
           badges: [ "black", "blue" ],
           points: [
              { points: 78, bonus: 8 },
              { points: 57, bonus: 7 }
           ]
         }
      ]
    )

三、演示查询

1、简单查询

    //查询所有文档,文档太多,此处及以下演示查询结果省略
    db.users.find( {} )     //与方式等价于db.users.find()
    db.users.findOne( {} )  //查询单条记录

    //等值查询,{ <field1: <value1, ... }
    db.users.find({_id:5}).pretty()
    db.users.find({age:19,status:"P"})     //多条件等值查询,隐式使用$and运算符

2、基于运算符的查询

    //基于运算符的查询,{ <field1: { <operator1: <value1 }, ... }
    //基于$in运算符
    db.users.find( { status: { $in: [ "P", "D" ] } } )   

    //基于$and运算符的查询
    db.users.find( {$and: [{ status: "A", age: { $lt: 30 } } ]})
    db.users.find( { status: "A", age: { $lt: 30 } } ) //此查询方法与上一条等价,隐式使用$and运算符

    //基于$or运算符的查询
    db.users.find( { $or: [ { status: "A" }, { age: { $lt: 30 } }]})

    //多条件组合查询,基于$lt,也有$or,还有隐式$and
    db.users.find(
       {
         status: "A",
         $or: [ { age: { $lt: 30 } }, { type: 1 } ]
       }
    )

3、内嵌文档查询

    //等值匹配内嵌文档
    db.users.find( { favorites: { artist: "Picasso", food: "pizza" } } )

    //等值匹配内嵌文档的特定键值,通过"键.成员名:值"的方式来进行
    db.users.find( { "favorites.artist": "Picasso" } )

4、数组查询

    //查询数组元素            //查询数组badges中包含black的文档
    db.users.find( { badges: "black" } ) 

    //匹配一个特定的数组元素  //查询数组badges中第一个元素为black的文档
    db.users.find( { "badges.0": "black" } )  //此处0表示数组的下标

    //匹配单个数组元素满足条件  //查询数组finished至少有一个元素的值大于15且小于20的文档
    db.users.find( { finished: { $elemMatch: { $gt: 15, $lt: 20 } } } )

    //匹配混合数组元素满足条件  //查询数组finished中任意的一个元素大于15,且另外一个元素小于20
    db.users.find( { finished: { $gt: 15, $lt: 20 } } )  //或者这个元素既大于15又小于20的文档

    //查询数组内嵌文档          //查询数组points元素1内嵌文档键points的值小于等于55的文档
    db.users.find( { 'points.0.points': { $lte: 55 } } )

    //查询数组内嵌文档         //查询数组points内嵌文档键points的值小于等于55的文档,此处未指定数组下标
    db.users.find( { 'points.points': { $lte: 55 } } )

    //查询数组元素至少一个内嵌文档满足所有条件的文档
    //如下,数组points内至少一个文档points键的值小于等于70,bonus键的值等于20的记录,这样的文档被返回
    db.users.find( { points: { $elemMatch: { points: { $lte: 70 }, bonus: 20 } } } )

    //查询数组元素任意一个内嵌文档满足所有条件的文档
    //如下,数组points内嵌文档任意一个文档points的值小于等于70,且数组内另外一个文档bonus值等于20
    //或者数组内某个内嵌文档points的值小于等于70,bonus的值等于20,这2种情形会被返回
    db.users.find( { "points.points": { $lte: 70 }, "points.bonus": 20 } )

四、限制查询返回的结果集

    { field1: <value>, field2: <value> ... }
    1 or true  显示该字段
    0 or false 不显示该字段

1、限制返回的列

    //查询结果中显示字段name及status,缺省情况下,文档的_id列会被返回
    > db.users.find( { status: "A" }, { name: 1, status: 1 } )
    { "_id" : 2, "name" : "bob", "status" : "A" }
    { "_id" : 3, "name" : "ahn", "status" : "A" }
    { "_id" : 6, "name" : "abc", "status" : "A" }

    //查询结果中显示字段name及status,且不显示_id列
    > db.users.find( { status: "A" }, { name: 1, status: 1, _id: 0 } )
    { "name" : "bob", "status" : "A" }
    { "name" : "ahn", "status" : "A" }
    { "name" : "abc", "status" : "A" }

    //返回查询中未列出的全部列名
    > db.users.find( { status: "A" }, { favorites: 0, points: 0 ,badges:0})
    { "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "finished" : [ 11, 25 ] }
    { "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "finished" : [ 6 ] }
    { "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "finished" : [ 18, 12 ] }

    //返回内嵌文档指定的列名,相反地,如果不显示内嵌文档的某个列,将在置0即可
    > db.users.find(
           { status: "A" },
           { name: 1, status: 1, "favorites.food": 1 }
        )
    { "_id" : 2, "name" : "bob", "status" : "A", "favorites" : { "food" : "meringue" } }
    { "_id" : 3, "name" : "ahn", "status" : "A", "favorites" : { "food" : "cake" } }
    { "_id" : 6, "name" : "abc", "status" : "A", "favorites" : { "food" : "pizza" } }

    //返回数组内内嵌文档的指定列,如下查询为数组points内嵌文档bonus列
    > db.users.find( { status: "A" },{ name: 1,"points.bonus": 1 } )
    { "_id" : 2, "name" : "bob", "points" : [ { "bonus" : 20 }, { "bonus" : 12 } ] }
    { "_id" : 3, "name" : "ahn", "points" : [ { "bonus" : 8 }, { "bonus" : 20 } ] }
    { "_id" : 6, "name" : "abc", "points" : [ { "bonus" : 8 }, { "bonus" : 7 } ] }

    //下面的查询使用了$slice操作符,这将仅仅返回符合status为A,且显示数组中的最后一个元素
    > db.users.find( { status: "A" }, { name: 1, status: 1, points: { $slice: -1 } } )
    { "_id" : 2, "name" : "bob", "status" : "A", "points" : [ { "points" : 64, "bonus" : 12 } ] }
    { "_id" : 3, "name" : "ahn", "status" : "A", "points" : [ { "points" : 55, "bonus" : 20 } ] }
    { "_id" : 6, "name" : "abc", "status" : "A", "points" : [ { "points" : 57, "bonus" : 7 } ] }

2、查询NULL值或不存在的键

    //插入文档
    > db.users.insert(
       [
          { "_id" : 900, "name" : null },
          { "_id" : 901 },
          { "_id" : 902,"name" : "Leshami" ,"blog" : "http://blog.csdn.net/leshami"}
       ]
    )

    //查询name自动为null的文档,注,以下查询中,不存在name列的文档_id:901的也被返回
    > db.users.find( { name: null } )
    { "_id" : 900, "name" : null }
    { "_id" : 901 }

    //通过$type方式返回name为null的文档,此时_id:901未返回
    > db.users.find( { name : { $type: 10 } } )
    { "_id" : 900, "name" : null }

    //通过$exists返回name自动不存在的文档
    > db.users.find( { name : { $exists: false } } )
    { "_id" : 901 }

五、小结

1、文档查询db.users.find()等价于db.users.find( {} )
2、基于and运算符的多个组合条件可以省略and,直接将条件组合即可
3、对于$and运算符内的条件,用[]括起来,相当于数组形式
4、对于数组查询,可以使用基于下标的方式精确配置特定的元素值
5、对于内嵌文档,可以使用”文档键.内嵌文档键”方式进行访问
6、对于数组内内嵌文档的方式,可以使用”数组名.下标.内嵌文档键”方式访问
7、对于哪些列名需要显示可以通过{ field1: <0|1>, … }来设定
8、本文参考:https://docs.mongodb.com/manual/tutorial/query-documents/

时间: 2024-08-03 15:58:14

mongoDB 文档查询的相关文章

mongoDB 文档更新

mongoDB对于文档的更新,既可以实现文档的更新,也可以实现文档随意的增减键(列),这是与传统的关系型数据库最大的不同之处,也就是所谓的无模式带来的一定程度上的便利.即mongoDB支持文档更新,也支持文档替换.本文给出了mongoDB更新语法及示例. 预备热身 Linux下快速安装MongoDB Windows平台下安装MongoDB mongoDB 启动与停止 mongo shell连接到mongoDB及shell提示符下执行js脚本 mongoDB简介及关键特性 SQL与mongoDB对

mongoDB 文档删除

mongoDB文档删除等同于关系型数据库中删除满足条件的单条或者多条记录,通常使用db.collection.remove()方法来实现文档的删除动作.mongDB文档删除属于原子性操作,仅仅在仅仅在单个文档级别.本文描述mongoDB文档删除操作并给出示例. 预备热身 Linux下快速安装MongoDB Windows平台下安装MongoDB mongoDB 启动与停止 mongo shell连接到mongoDB及shell提示符下执行js脚本 mongoDB简介及关键特性 SQL与mongo

mongoDB 文档插入

mongoDB文档插入与SQL表insert方式基本相同.在关系数据库中,我们需要先定义表,然后才能将记录插入到文档,而在mongoDB中,由于无需预定义模式,因此,在集合不存在的情形下,直接insert就会生成新的集合.如果已经存在,则会在现有的集合内增加新文档.而且插入的文档可以与集合上的其他文档使用不同的键或键值类型.本文主要描述mongoDB文档插入,供大家参考. 预备热身 Linux下快速安装MongoDB Windows平台下安装MongoDB mongoDB 启动与停止 mongo

MongoDB 文档字段增删改

MongoDB 基于CRUD(create,read,update,delete)方式实现了对集合上的文档进行增删改查.对于集合上字段的增删改,可以使用set或者unset修改器来实现.也可以使用文档替换的方式来实现.本文主要描述集合上字段的增删改,以及基于选项upsert的更新. 关于MongoDB文档更新可以参考:MongoDB 文档更新 一.语法描述 db.collection.update( <query>, //查询或过滤条件 <update>, //修改器(被修改键及内

MongoDB文档和集合

1.文档是MongoDB最核心的概念,本质上是一种类JOSN的BSON格式的数据. BSON是一种类JSON的二进制格式数据,它可以理解为在JSON基础上添加了一些新的数据类型,包括日期.int32.int64等. BSON是由一组组键值对组成,它具有轻量性.可遍历性和高效性三个特征.可遍历性是MongoDB将BSON作为数据存储的主要原因. { field1:value1, field2:value2, field3:value3, field4:value4, } 2.使用MongoDB文档

Elasticsearch增删改查 之 —— mget多文档查询

之前说过了针对单一文档的增删改查,基本也算是达到了一个基本数据库的功能.本篇主要描述的是多文档的查询,通过这个查询语法,可以根据多个文档的查询条件,返回多个文档集合. 更多内容可以参考我整理的ELK文档教程 multi Get 多字段查询可以设置多个文档查询条件,每个查询条件在结构上都比较类似: curl 'localhost:9200/_mget' -d '{ "docs" : [ { "_index" : "test", "_typ

MongoDB文档对象字段属性合并的2种转换方法

现在,对MongoDB中文档对象冗余数据有中业务要求,就是对同种属性的字段进行合并成一个集合,效果如下图所示: 实现上述数据转换有2中方法:一种是基于NoSQL语言的实现方式,一种是基于kettle的业务数据转换. 1.基于NoSQL语言的实现方式 首先,在MongoDB里准备一个文档数据: [mongo@mongo ~]$ mongo MongoDB shell version: 3.2.7 connecting to: test > show dbs local  0.000GB zhul 

MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码_MongoDB

MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 下面给大家介绍MongoDB查询文档操作的实例 先把student删除,再重新插入数据 > db.student.drop() true > db.student.insert([{ "_id" : 1, "

转 MongoDB数据库关系表示和设计:(1)嵌套文档和引用链接

使用数据的时候,一个数据项常常和另外的一个或多个数据项产生关系,比如一个"人"对象,有一个名字,可能有多个电话号码,以及多个子女,等等.   在传统的SQL数据库中,关系被分为一个个表(table),在表中,每个数据项以主键(primary key)标识,而一个表的主键又作为另一个表的外键(reference key),在两个表之间引用.当遇上多对多关系的时候,还需要一个额外的关联表(reference table),将多对多关系转化成两个一对多关系.   而在MongoDB中,表示关