我如何在MongoDB中执行SQL Join等价物?
我如何在MongoDB中执行SQL Join等价物?
例如,假设您有两个集合(用户和评论),并且想要将所有评论与pid = 444以及每个用户的信息一起提交。
comments
{ uid:12345, pid:444, comment="blah" }
{ uid:12345, pid:888, comment="asdf" }
{ uid:99999, pid:444, comment="qwer" }
users
{ uid:12345, name:"john" }
{ uid:99999, name:"mia" }
有没有办法将所有评论与某个领域(例如... ... find({pid:444}))以及与每个评论相关的用户信息放在一起?
目前,我首先得到符合我的标准的评论,然后找出结果集中的所有uid,获取用户对象,并将它们与评论结果合并。 似乎我做错了。
从Mongo 3.2开始,这个问题的答案大多不再正确。 添加到聚合管道中的新的$ lookup操作符与左外连接基本相同:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
从文档:
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}
当然,Mongo不是关系数据库,开发人员正在小心地推荐用于$ lookup的特定用例,但至少从3.2开始,现在可以使用MongoDB进行连接。
官方mongodb网站上的这个页面正好解决了这个问题:
http://docs.mongodb.org/ecosystem/tutorial/model-data-for-ruby-on-rails/
当我们显示故事列表时,我们需要显示发布故事的用户的姓名。 如果我们使用的是关系数据库,我们可以在用户和商店上执行连接,并在一个查询中获取所有对象。 但是MongoDB不支持连接,所以有时需要一些非规范化。 在这里,这意味着缓存'用户名'属性。
关系纯粹主义者可能已经感到不安,好像我们违反了一些普遍法律。 但是让我们记住,MongoDB集合不等同于关系表; 每个都有独特的设计目标。 规范化的表格提供了一个原子的,孤立的数据块。 然而,文件更接近地代表整个对象。 在社交新闻网站的情况下,可以认为用户名是发布故事的内在原因。
我们可以使用mongodb客户端控制台,通过几行简单的函数将一个集合中的所有数据合并/加入,现在我们可以执行所需的查询。 在一个完整的例子下,
.-作者:
db.authors.insert([
{
_id: 'a1',
name: { first: 'orlando', last: 'becerra' },
age: 27
},
{
_id: 'a2',
name: { first: 'mayra', last: 'sanchez' },
age: 21
}
]);
.-类别:
db.categories.insert([
{
_id: 'c1',
name: 'sci-fi'
},
{
_id: 'c2',
name: 'romance'
}
]);
.-书
db.books.insert([
{
_id: 'b1',
name: 'Groovy Book',
category: 'c1',
authors: ['a1']
},
{
_id: 'b2',
name: 'Java Book',
category: 'c2',
authors: ['a1','a2']
},
]);
- 图书借阅
db.lendings.insert([
{
_id: 'l1',
book: 'b1',
date: new Date('01/01/11'),
lendingBy: 'jose'
},
{
_id: 'l2',
book: 'b1',
date: new Date('02/02/12'),
lendingBy: 'maria'
}
]);
。- 魔术:
db.books.find().forEach(
function (newBook) {
newBook.category = db.categories.findOne( { "_id": newBook.category } );
newBook.lendings = db.lendings.find( { "book": newBook._id } ).toArray();
newBook.authors = db.authors.find( { "_id": { $in: newBook.authors } } ).toArray();
db.booksReloaded.insert(newBook);
}
);
.-获取新的收集数据:
db.booksReloaded.find().pretty()
.-回应:)
{
"_id" : "b1",
"name" : "Groovy Book",
"category" : {
"_id" : "c1",
"name" : "sci-fi"
},
"authors" : [
{
"_id" : "a1",
"name" : {
"first" : "orlando",
"last" : "becerra"
},
"age" : 27
}
],
"lendings" : [
{
"_id" : "l1",
"book" : "b1",
"date" : ISODate("2011-01-01T00:00:00Z"),
"lendingBy" : "jose"
},
{
"_id" : "l2",
"book" : "b1",
"date" : ISODate("2012-02-02T00:00:00Z"),
"lendingBy" : "maria"
}
]
}
{
"_id" : "b2",
"name" : "Java Book",
"category" : {
"_id" : "c2",
"name" : "romance"
},
"authors" : [
{
"_id" : "a1",
"name" : {
"first" : "orlando",
"last" : "becerra"
},
"age" : 27
},
{
"_id" : "a2",
"name" : {
"first" : "mayra",
"last" : "sanchez"
},
"age" : 21
}
],
"lendings" : [ ]
}
我希望这条线可以帮助你。
链接地址: http://www.djcxy.com/p/37063.html上一篇: How do I perform the SQL Join equivalent in MongoDB?
下一篇: Hibernate criteria: Joining table without a mapped association