是mongoDB的初学者。我有两本书和作者。 [name和workswritten]分别是公共列。使用内连接我必须在Book和Author中发出一些列。就像这个sql查询:
select book.name,book.editions,book.characters,author.name
from dbo.book book
inner join dbo.author author on book.name=author.works_written
我需要在MongoDB中执行相同的查询。地图/减少?
答案 0 :(得分:2)
MongoDB不支持JOIN操作。当您需要此功能时,您必须通过查询两个集合来自己实现它。
出于这个原因,使用嵌入而不是链接通常是一个很好的策略。
Map / Reduce作业通常是一项非常昂贵的操作。它只应偶尔用于数据挖掘。
答案 1 :(得分:2)
我需要使用mapreduce函数来完成它。
db
对象在MR中已被弃用了很长时间,因此无法在MR中同时获取两个表。
还有另一个解决方案:两个MR。您在第一个集合上运行MR,首先输出到所需的集合,然后使用第二个MR使用out
或reduce
之类的merge
选项输出到同一个集合加入“两个集合。
当然这很慢,所以更好的方法是不要这样做。至于:
select book.name,book.editions,book.characters,author.name
from dbo.book book
inner join dbo.author author on book.name=author.works_written
此查询可以通过从书籍集合中流式传输光标,然后非常快速地对每个您迭代的书籍(可以在MongoDB中执行此操作)获取作者详细信息。
您还可以从书籍中获取一组作者ID,然后一次查询作者集合,并在客户端对这两者进行排序。
答案 2 :(得分:1)
mongodb不是关系数据库 - 所以这里不可能有任何类型的连接。加入很难扩展。
mongodb实现连接的常用方法是数据非规范化。在您的情况下,您可以将作者姓名非规范化为书表。那么您的查询将不需要加入。这是架构示例:
book
{
_id,
name,
editions,
characters,
author_name
}
请注意,每次更新作者集时,您都需要更新图书集中的author_name
。
另一个解决方案 - 每本书的作者姓名的额外请求,但它的工作速度会慢得多。
答案 3 :(得分:1)
试试这个: -
db.book.aggregate([
{
$lookup:
{
from: "author",
localField: "name",
foreignField: "works_written",
as: "nameWorkData"
}
}
])
答案 4 :(得分:0)
您可以比较下面的SQL和mongoDB(NoSQL)代码:
SQL代码:
Users::groupBy('name')->get();
mongoDB(NoSQL):
SELECT *, [output array field]
FROM collection
WHERE [output array field] IN (SELECT *
FROM [collection to join]
WHERE [foreignField]= [collection.localField]);