【发布时间】:2018-02-20 22:57:04
【问题描述】:
有几个模型有很大不同并且属于不同的集合,但它们有共同的字段,当查询结果聚合在一起时将使用这些字段。
const BlogPost = mongoose.model('BlogPost', new mongoose.Schema({
title: String,
body: String,
promoteAtMainPage: {
type: Boolean,
default: false
},
timestamp: Date,
active: Boolean,
/ * the rest are different */
});
const Article = mongoose.model('Article', new mongoose.Schema({
title: String,
body: String,
promoteAtMainPage: {
type: Boolean,
default: false
},
timestamp: Date,
active: Boolean,
/ * the rest are different */
});
仅使用结果中的常用字段(title、body、timestamp)。
此外,如果文档中缺少promoteAtMainPage,则在这些模型中应区别对待(在一种情况下默认为true,在另一种情况下默认为false)。
目前这是通过结果处理完成的:
let blogPosts = await BlogPost.aggregate([{ $match { active: true } }, { $sort: { timestamp: -1} }, { $limit: 100 } }]);
for (let blogPost of blogPosts)
blogPost.promoteAtMainPage = ('promoteAtMainPage' in blogPost)
? blogPost.promoteAtMainPage
: false;
let articles = await Article.aggregate([{ $match { active: true } }, { $sort: { timestamp: -1} }, { $limit: 100 } }]);
for (let article of articles)
article .promoteAtMainPage = ('promoteAtMainPage' in article )
? article .promoteAtMainPage
: true;
let mainPagePosts = [...blogPosts, ...articles]
.filter(post => post.promoteAtMainPage)
.sort((a, b) => b.timestamp - a.timestamp)
.slice(0, 100);
这会导致请求 200 个文档而不是 100 个文档,并执行额外的sort。
在这种情况下,是否可以仅通过 Mongoose 或 Mongodb 聚合来自不同集合的结果?
Mongodb 是否也可以处理缺少promoteAtMainPage 字段的情况,或者唯一合理的处理方法是对所有现有文档应用迁移并添加默认的promoteAtMainPage 值?
【问题讨论】:
-
你的问题是这些在两个集合中。您可以通过将它们放在一个集合中来解决它。 MongoDB 没有架构,因此您可以这样做。您可以使用discriminators. 为每种类型应用架构。 MongoDB 没有“联合查询”之类的东西。 MongoDB 的解决方案是“放入同一个集合中”。
-
@NeilLunn 我认为这是一个选项,但这些模型非常不同,所以这几个字段只是它们的共同点。直到此刻,才有理由与歧视者一起加入他们。所以鉴别器和后处理是这里唯一的可能性,不是吗?
-
这就是为什么您需要阅读它,因为我现在太累了,无法写出冗长的答案来解释所有这些。提到了一个简单的事实。您不能以这种方式“加入”集合。所以把数据放在一个集合中。
-
感谢您对 Mongo 主题的帮助,但这种长篇大论是不必要的。我知道在 Mongo 中是如何完成的,并且我知道将所有文档存储在同一个集合中将有助于避免这个问题(并且可能会添加其他我还不知道的问题)..这并不排除可能存在我不知道的 Mongo(ose) 功能在这里可以提供帮助的可能性。现在我正在为此评估
$out,但仍然不确定这是否是个好主意。