当涉及到从MongoDB实例中读取数据时,你有两个选择,一个是使用标准查询语言的查询,一个是聚合管道。虽然你通常可以在许多使用情况下使用这两种方法,但在如何使用它们以及它们适合哪些使用情况方面存在着差异。
为了使用下面的例子,你可以在你的MongoDB实例中插入以下文件。
如果你以前没有在MongoDB中插入过多个文档,你可以在这里阅读相关内容:
db.podcasts.insertMany([
{id: 1, name: "Podcast 1", category: "Business", rss: "https://mypodcast1.com/podcast/rss"},
{id: 2, name: "Podcast 2", category: "Business", rss: "https://podcast2.net/rss"},
{id: 3, name: "Podcast 3", category: "Health & Wellness", rss: "https://podcast3.xyz/feed/rss"},
{id: 4, name: "Podcast 4", category: "Technology", rss: "https://podcast4.com/rss"}
]);
db.episodes.insertMany([
{podcast_id: 3, title: "Anabolic Recipes", published_on: "2020-01-02"},
{podcast_id: 4, title: "Getting Going with Go", published_on: "2021-02-24"},
{podcast_id: 1, title: "Talk About Money Early", published_on: "2022-01-01"},
{podcast_id: 1, title: "Charge More by Saying No", publshed_on: "2021-12-01"},
{podcast_id: 2, title: "Candidate Interview Strategies", published_on: "2020-05-01"},
{podcast_id: 4, title: "The Magic of Pattern Matching", published_on: "2022-01-01"}
]);
易用性
MongoDB的查询语言和它的相关方法是为了直接使用。与聚合相比,它们更容易阅读,而且不容易出错。
以想要过滤掉并只返回某些文档为例。使用查询语言就像传入一个描述如何过滤对象的对象到find 方法一样简单。
db.podcasts.find({category: "Business"});
要用聚合做同样的事情,需要使用$match 聚合阶段:
db.podcasts.aggregate([
{ $match: {
category: "Business"
}}
]);
使用案例
虽然标准查询语言的优势在于它的简单性,但这也限制了它能解决什么问题。聚合基本上是相反的,更难使用但更强大,允许它们完成某些简单查询无法完成的用例。
标准查询语言是一个很好的解决方案:
- 只返回/影响某些符合提供的过滤器的文件
- 当读回数据时,只包括某些字段
任何超出这些场景范围的事情,要么更好地完成,要么需要通过聚合来完成。
一个这样的例子,也是我个人最早需要使用聚合的例子,就是想在SQL查询中执行类似于连接的操作。
使用现有的查询方法和语言根本无法做到这一点,但可以使用$lookup 聚合阶段来完成。
如果我们想得到我们所有的播客,包括与该播客相关的每一集:
db.podcasts.aggregate([
{ $lookup: {
from: "episodes",
localField: "podcast_id",
foreignField: "id",
as: "episodes"
}}
]);