在上一篇文章中,我们学习了如何创建数据库和集合,并且我们还开始使用 CRUD 操作来使用数据库来创建文档。

在文章的最后,我建议您使用数据库工具的mongoimport命令,导入更大的集合或数据集,从而能够以更复杂的方式使用 MQL。

如果他们没有,我建议进入条目 3 并按照说明进行操作。

读取文档的CRUD操作

今天我们将学习如何使用 MongoDB 的查询语言 MQL 来精确查询我们的redtatuaje数据库。

正如我们在上一篇文章中了解到的,我们将使用终端连接到我们的本地服务器,并使用所需的数据库和集合。

连接一个 mongodb 服务端本地

操作 CRUD findOne()

我们要做的第一件事是随机检查数据库中的任何文档,以查看文档的结构。

我们将通过首先运行show collections来执行此操作,以查看我们有哪些可用的集合并确保我们已正确导入数据,因此我们可以按照本文中的说明进行操作。

显示 mongodb 集合

然后运行

db.artistas.findOne()

进入全屏模式 退出全屏模式

mongodb 方法 findOne()

findOne()返回它找到的第一个满足特定查询条件的文档,即从找到文档的自然顺序中的第一个。如果集合是有界的(通常以 MB 为单位),则自然排序对应于插入顺序。在这种情况下,我们看到它返回对应于artist_id: 743的那个,对应于name: "Alex Holt"

findOne()的可选参数

findOne() 方法接受传递给它的两个可选参数以确定该条件。例如,我们可以说

db.artistas.findOne(query, projection)

进入全屏模式 退出全屏模式

查询本身和投影条件。

查看上图,我们可以看到对于 id 为 743 的艺术家,属性owns_studio的值为Yes。我们可以要求 MongoDB 按自然顺序返回第一个,因此该值为No

db.artistas.findOne({ "owns_studio": "No"})

进入全屏模式 退出全屏模式

findOne() 通过向其传递查询

在这种情况下,我们可以看到,艺术家 id 现在是701,对应于name: "Sue King"的艺术家。

查询投影(Projection)

但是我们已经说过,这种方法还接受了第二个附加参数,投影。这意味着什么?

MongoDB 将始终返回投影的文档的字段。默认情况下,所有字段都是投影的,即它们的投影值为 1 或true

1或0和true以外的值,指定包含在投影中

但是,如果我们显式地转换一个字段,则只有该字段将与_id的值一起返回,只有当它的转换值显式设置为 0 或false时才会被排除。

让我们看一个例子

db.artistas.findOne({ "owns_studio": "No"}, {"owns_studio": 1, "name": 1})

进入全屏模式 退出全屏模式

findOne() 带查询和投影

如果我们想省略_id字段的值,我们必须显式地传递 0(或false)

db.artistas.findOne({ "owns_studio": "No"}, {"owns_studio": 1, "name": 1, "_id": 0})

进入全屏模式 退出全屏模式

排除MongoDB投影中的_id

我们将在本系列的后面更深入地研究Projection,因为有更多的投影方法,以及更复杂数据的特殊方法,如嵌套数据或数组。

操作 CRUD find()

直到现在,当我们要求 MongoDB 找到一个,或者 findOne() 时,它总是只返回一个......但是当我们想要一个列表时会发生什么?

所以我们必须执行

db.artistas.find()

进入全屏模式 退出全屏模式

但是等等......发生了什么事?您是否已将我们导入到集合中的 1000 份文档退回?

否。此方法返回一个cursor,它是对查询返回的结果集的引用,并且可以迭代。也就是说,我们可以看到更多的内容,然后访问我们想要的文档。

默认情况下,find() 的光标会向我们显示 101 个结果,只要不超过最大文档大小,即 16MB(正如我们在系列条目 1 中看到的),获取更多结果的方法之一是执行it,正如我们在图像中看到的那样。

iterate el cursor en mongoDB

我们还可以将光标分配给一个变量(记住我们在一个功能齐全的 REPL 中!)并使用它的一些方法。例如。

let tatuadores = db.artistas.find({ "owns_studio": "Yes" });

while (tatuadores.hasNext()) { 
  printjson(tatuadores.next());
}

进入全屏模式 退出全屏模式

这里我们使用hasNext()方法来评估是否有更多的文档满足查询,在光标处,我们使用next()方法来迭代它们,而hasNext()返回true

其他游标方法是forEach()toArray()objsLeftInBatch(),它们告诉我们在执行迭代(或返回集)之后批处理中有多少对象。

我们还可以使用isExhausted()方法来检查光标中是否真的没有更多的对象或文档。

记住每个文档都映射到一个对象。

游标方法的完整列表可以在这里找到

find()与早期版本的控制台一起使用时,它用于连接pretty()方法,以便将光标中的结果格式化。mongosh中默认执行pretty()

我们来看一个使用forEach()的例子:

let tatuadores = db.artistas.find({ "owns_studio": "Yes" });

tatuadores.forEach((tatuador) => { 
  if (tatuador.payment_method === "Credit Card Only") { 
    printjson(tatuador);
  }
});

进入全屏模式 退出全屏模式

将光标限制在批处理中特定数量的结果

在一个非常大的数据库中,文档非常小,我们可能会返回太多的对象。如果我们想明确限制它们以提高性能,我们可以使用limit()方法,就像这样。

db.artistas.find({"payment_method" : "Credit Card Only"}).limit(5)

进入全屏模式 退出全屏模式

有关limit()方法的更多信息,请参见此处。

find()的可选参数

Find 还接受两个可选参数的设置:查询和投影。

使用查询运算符的复杂查询

我们将开始使用比较运算符进行更复杂的查询。在其他帖子中,我们将探讨逻辑、元素、评估、数组和地理空间。当然,我们将发表关于投影的具体帖子。

让我们开始吧!

找到一个与查询中传递的值等效的值: operator$eq

该运算符允许我们查询数据库以查找具有等于传递的特定值的所有文档。例如,让我们找到所有没有自己工作室的艺术家。

我们将始终将查询限制为 5 以减少响应时间,但这不是要求。

db.artistas.find({ "owns_studio": { $eq: "No" } }).limit(5)

进入全屏模式 退出全屏模式

查询格式为:

{ <campo>: { $eq: <valor> } }

进入全屏模式 退出全屏模式

我们可以说这相当于执行这个查询

db.artistas.find({ "owns_studio": "No" }).limit(5)

进入全屏模式 退出全屏模式

但是,当使用运算符时,我们可以将它们组合起来或使用逻辑运算符,以进行更复杂的查询,我们将在我们的进展中看到。

查找大于传递值的值:运算符$gt

该运算符允许我们找到传递字段的值大于指定值的文档。在这种情况下,标识符大于 500 的所有艺术家

db.artistas.find({ "artist_id": { $gt: 500 } }).limit(5)

进入全屏模式 退出全屏模式

查询格式为:

{ <campo>: { $gt: <valor> } }

进入全屏模式 退出全屏模式

同样我们可以找到大于或等于传递值的值,用$gte,小于$lt,或者小于或等于传递的值,用$lte。语法是一样的。

zwz 100107 zwz 100109 zwz 100110 zwz 100108 找出所有不同于:运算符$ne的值

ne将意味着not equalno igual。我们使用它来查找所有值不等于过去的文档。

db.artistas.find({ "artist_id": { $ne: 500 } }).limit(5)

进入全屏模式 退出全屏模式

当然,我们不一定要进行数值比较。我们正在比较文字值。因此,我们可以传递任何类型。_

db.artistas.find({ "name": { $ne: "Cordelia Swanson" } }).limit(5)

进入全屏模式 退出全屏模式

上面的比较也是如此。例如:

db.artistas.find({ "country": { $lt: "PE" } }).limit(5)

进入全屏模式 退出全屏模式

where 将返回所有小于“PE”的值作为国家代码,按字母顺序排列。

使用比较运算符比较日期

我们也可以将它们用于日期。例如,如果我们要查找一年或更早之前加入该平台的所有艺术家,我们会这样做:

db.artistas.find({ "joined_network": { $lte: new Date("2021-08-12") } }).limit(5)

进入全屏模式 退出全屏模式

排除包含数组字段中值的结果:运算符$nin

此运算符not in允许我们从光标中排除对象,如果它们在数组类型字段中包含某个值。

例如,假设我们要从结果滑块中过滤掉所有致力于风格geometricrealism的艺术家。

db.artistas.find({ "styles": { $nin: ["geometric", "realism"] } }).limit(10)

进入全屏模式 退出全屏模式

$nin还可用于从光标中排除不包含某个字段的文档。

有关此条件运算符的更多信息,请参阅文档

MQL 和 el mongosh 对比与司机一起操作

在编写应用程序时,不应将 MongoDB 控制台中的 MQL 操作方法与不同驱动程序提供的方法混淆。

这些驱动程序(或中间件)中的许多驱动程序(或中间件)创建抽象层以简化运算符的组合,并且可能提供对数据库进行操作的不同方法。

在下一篇文章中,我们将使用逻辑运算符。直到那时!

特别感谢@wassimchegham总是审查我的屏幕截图和@dfreniche我要求同行评审,他回答“RIGHT NAO!” <3

Logo

MongoDB社区为您提供最前沿的新闻资讯和知识内容

更多推荐