65.9K
CodeProject 正在变化。 阅读更多。
Home

MongoDB 教程 - 第二天

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (29投票s)

2016年4月10日

CPOL

5分钟阅读

viewsIcon

38860

MongoDB教程 - MongoDB特定查询

引言

欢迎来到 MongoDB 教程的第二天。这是 MongoDB 教程系列中的第二部分。在本文的第一部分,我们涵盖并学习了一些基本的 MongoDb 查询和操作。在上一篇文章中,我们将一些 SQL 查询与 MongoDB 查询进行了比较。如果有人是 MongoDB 新手,建议您在阅读本文之前先浏览我的前几篇文章。在本文中,我们将介绍一些 MongoDB 特有的查询。

您可以在这里阅读我之前的文章。

背景

在本文的第一部分,我们涵盖了 MongoDB 的以下主题

  1. No-Sql 简介(No-SQL 下的不同数据库类型)
  2. 如何在您的机器上安装和设置 MongoDB。
  3. Robomongo 简介(MongoDB 开源管理工具)
  4. MongoDB 术语
  5. 如何在 MongoDB 中插入文档
  6. 如何在 MongoDB 中选择文档
  7. Where 子句,大于和小于
  8. Like,逻辑 AND 和逻辑 OR
  9. MongoDB 中的 in 操作符,MongoDB 中的 CountSort 记录
  10. MongoDB 中的 UpdateDeleteRemoveDrop
  11. MongoDB 中的 TopDistinctBackup

我之前文章中关于 MongoDB 的一些要点

  1. MongoDB 是一个文档存储数据库。
  2. MongoDB 是无模式的。
  3. MongoDB 以 JSON 格式存储数据(我们称之为 BSON(二进制 JSON))。
  4. JSON 文档以键值对的形式存储数据,例如 {“X”:1,”Y”:2,”Z”:3}

那么,是时候开始学习更多 MongoDB 的概念了,首先是 MongoDB 中可用的数据类型。

本文的收获

  1. MongoDB 的无模式行为
  2. $exists
  3. $type
  4. MongoDB 的不同数据类型
  5. $in, $all$nin
  6. 嵌入式文档和嵌入式文档上的查询

MongoDB 是无模式的

我们一直在谈论 MongoDB 的无模式行为,这也是 MongoDB 如今如此受欢迎的关键原因。因此,让我们来理解无模式的含义。

假设我们在 Test 数据库中有一个名为 Employee 的集合(请参阅我之前的文章,了解如何在 MongoDBDatabase 中创建数据库和集合,如下所示)

Employee 集合中插入文档

db.Employee.insert({Name:"Vijay",Age:30,Email:"VijayRana1091@gmail.com"})

在上述文档中,我们有 NameEmail 作为 String 类型,Age 作为 Number 类型。

现在,让我再插入一个文档,这次我将添加一个名为 address 的新列。

db.Employee.insert({Name:"Vijay",Age:30,Email:"VijayRana1091@gmail.com",Address:"Delhi"})

结果如下

现在,请想想关系型数据库管理系统 (RDMS)。在 RDMS 中,我们必须先 Alter 表才能添加新列,但在 MongoDB 中,我们不需要添加新列,因为 MongoDB 中的所有文档都可以具有不同的模式。

让我再向 Employee 集合插入一个文档。

db.Employee.insert
({
    Name:"Vijay",Age:30,Email:"VijayRana1091@gmail.com",
    Address:"Delhi",Interest:["Cricket","Music"]
})

哇,我们甚至可以将 Array 插入到 MongoDB 的文档中。实际上,JSON 中有两种基本结构

  1. Array:事物列表用项目列表 [………] 表示
  2. Dictionaries:关联映射 {key:Value}

那么,我们已经掌握了无模式的概念,可以继续前进。

如上例所示,某些文档可能包含 Address 列,而在同一集合中的另一个文档则不一定包含相同的列。简而言之,在一个集合中,不同的文档可以具有不同的列/模式。但是,假设**您想查找集合中存在 Address 列的所有文档。**在 MongoDB 中,我们使用 $exist 来执行此类查询。

$exists

我们有如下的 Employee 集合

在上方的集合中,如下所示,假设我有一些文档没有 Address,而有些文档则包含 Address 列以及其他列。现在,假设我想检索 Address 存在的记录。

让我再向 Employee 集合插入一个文档,如下所示

db.Employee.insert
({
    Name:111,Age:30,Email:"VijayRana1091@gmail.com",Address:"Delhi"
})

这次,我在 Name 列中插入了一个整数值。是的,我们也可以这样做。这就是无模式特性的魔力。我可以将任何类型的值插入到任何列中。

但是,假设我想找出 Name 是 string 类型的所有文档,该如何查找?

我们为此使用 $type

$type

到目前为止,我的 employee 集合中有以下记录。我有三个文档,其中的 namestring 类型,一个文档中的 name 是数字类型。

现在,我想找出 Name 是 string 类型的所有文档

在 MongoDB 中,我们使用 2 表示 string,使用 1 表示 number。所有数据类型的完整列表如下表所示。

我们可以在 $type 中使用以下数据类型。

MongoDB 中的数据类型

MongoDB 中一些常用的数据类型如下

数据类型 数字 含义
双精度浮点型 1 用于 float
字符串 2 String 是最常用的 DataType。在 MongoDB 中,string 必须是 UTF-8 有效的。
对象 3 用于嵌入式文档
数组 4 用于将列表或多个值存储到一个键中
二进制数据 5 用于存储二进制数据
未定义 6  
对象 ID 7 用于存储文档的 ID
布尔值 8 用于存储布尔值(true/false
日期 9 用于存储日期和时间
Null (空值) 10 用于存储 Null
正则表达式 11 用于存储正则表达式
32 位整数 16 用于存储 32 位整数
时间戳 17 用于存储日期和时间
64 位整数 18 用于存储 64 位整数

接下来呢?让我插入一些更多记录

db.Employee.insert
({
    Name:"Preeti",Age:26,Email:"Preeti@gmail.com",Address:"Delhi",
          Interest:["cooking","Music"]
})

db.Employee.insert
({
    Name:"Ajay",Age:26,Email:"Preeti@gmail.com",Address:"Delhi",
                Interest:["Driving","Music"]
})

现在,假设我们想找出兴趣是 Music 的所有文档,即这次我们想在数组内进行搜索。

我们也可以像下面这样在数组内搜索

db.Employee.find({Interest : "Music"})

因此,我们可以说 MongoDB 中的匹配是多态的。

$in, $all 和 $nin

如果我们想找出同时将 cookingMusic 作为 interest 的所有文档,那么我们可以使用 $all

db.Employee.find({Interest : {$all:["cooking","Music"]}})

如果我们想找出兴趣包含 music 或 driving 的所有文档,那么我们将使用 $in 操作符。

db.Employee.find({Interest : {$in:["Driving","Music"]}})

如果我们想找出兴趣不是 cooking 的所有记录,那么我们将使用 $nin,如下所示。

    db.Employee.find({Interest : {$nin:["cooking"]}})

上面的查询将返回 Interest 不是 cooking 的所有文档。

嵌入式文档和点表示法

我们也可以在 MongoDB 中拥有嵌入式文档,如下所示。

db.Employee.insert
({
    Name:{firstName:"Preeti",LastName:"Rana"},Age:26,Email:"Preeti@gmail.com",
	Address:"Delhi",Interest:["cooking","Music"]
})

db.Employee.insert
({
    Name:{firstName:"Vijay",LastName:"Rana"},Age:30,Email:"Vijay@gmail.com",
	Address:"Delhi",Interest:["cooking","Music"]
})

要指定嵌入式文档中的条件,我们可以使用点表示法,如下所示。

db.Employee.find({"Name.firstName":"Vijay"})

上面的查询将搜索所有在 NamefirstNameVijay 的文档。

在本系列的下一篇文章中,我将介绍 Aggregation(groupBy)Indexes$Text$lookup。敬请期待。

历史

  • 2016 年 4 月 10 日:初版
© . All rights reserved.