繁体   English   中英

学习MongoDB如何使用2个集合中的数据查找

[英]Learning MongoDB how to find using data from 2 collections

我有2个相关的收藏。 甲板与事实。

甲板看起来像这样:

{
   _id: ObjectId("123456789123456789"),
   title: "test deck"
   isActive: true
}

事实看起来像这样

{
   _id: ObjectId("111111324324434"),
   deckId: ObjectId("123456789123456789")
   title: "test fact"
}

我来自SQL背景,所以我要SELECT * FROM facts LEFT JOIN decks ON decks._id = facts.deckId WHERE deck.isActive = true

我能弄清楚的唯一方法是通过微型脚本。

var deckIds = db.decks.find({isActive: false}, {_id: true}).toArray().map(function(item) {
 return item._id; 
});
db.facts.find({deckId: {$in: deckIds}}); 

这是最好的方法吗? 在Mongo中,是否有更高效的方法来完成所有这些工作? 我看着map-reduce,但是我不知道在那里怎么做,这似乎是更多的代码。 我最后要做的是删除具有deck.isActive = false的事实。

MongoDB是一个NoSQL数据库,因此您不会获得本机的JOIN功能。 您应该像这样做一样手动进行操作。

但是,要考虑的一件事是数据建模。 与关系数据库中被认为是最佳化的最佳实践相反,NoSQL模型倾向于非正规化。

因此,也许您的事实文档可能包含其他卡片组的字段,以查询简化的缘故。 我并不是说这对您来说是最好的选择,而只是警告您在非关系数据库中,在数据建模方面您应该有所不同。 当然,您选择的每个模型都会对写作和阅读产生影响,这在很大程度上取决于您的工作量。 这需要一些练习和练习,但是您可以遵循一些准则。 请看官方文档

Packt Publishing也有一本关于该主题的好书,叫做MongoDB Data Modeling

好消息是,MongoDB在功能(您可以拥有嵌套文档,数组,就地操作等)方面非常强大,因此您可以通过多种选择来实现所需的功能。

另外,不要忘记根据查询和更新来创建索引_id字段会自动建立索引,其余的不会自动建立索引)。

虽然这是“ SQL”的思维方式,但Mongo确实通过在Mongo 3.2中添加的$ lookup( https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/ )支持了这种工作。 我建立了您的数据,但名称使用小写字母; 以下工作可以快速加入。

db.facts.aggregate([{$lookup: {from: "decks", localField: "deckId", foreignField: "_id", as: "deck_data"}}]);

产量

{ "_id" : ObjectId("56c5eb065b2de3fa9f8a9d0c"), "title" : "test fact", "deckId" : ObjectId("56c5eadb5b2de3fa9f8a9d0b"), "deck_data" : [ { "_id" : ObjectId("56c5eadb5b2de3fa9f8a9d0b"), "title" : "test deck", "isActive" : true } ] }

您可以通过将其他对象添加到阵列中来应用其他聚合步骤。 我建议$ match(相当于Find())和$ project(允许选择字段)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM