我有一个管理界面网站,用户可以在其中创建新闻文章,也可以选择本文应出现在哪些网站上。 (有许多网站连接到同一个Mongo数据库)
每个网站都有一个包含文章ID的数组。当我去其中一个网站时,我循环播放这个数组并从中获取属于该网站的所有文章(来自Articles
集合):
Articles.findOne({_id:id});
但是,如果我想进行更多高级查询(例如日期排序),则会出现问题。限制等等。
与此同时,我不希望直接从Articles
集合过滤特定网站的所有文章,因为它接收价格昂贵? (它包含来自所有网站的所有文章)并且在每个网站上本地保存每篇文章都会产生重复。
我想知道存储这些新闻文章的好方法是什么,并且仍然可以为每个网站快速获取它们?
------------------------
我目前这样做是为了从网站上获取所有文章并按日期排序。但是现在我还需要设置一个限制,只需从特定类别中获取文章等等,这会变得非常麻烦:
var websites = Websites.find({name : "SITENAME"},{}).fetch();
var now = new Date();
var articles = [];
websites[0].articles.forEach(function(id) {
article = Articles.findOne({_id:id});
if (article != undefined && article.publishedDate < now) {
articles.push(article);
}
});
articles.sort(function(a, b) {
a = a.publishedDate;
b = b.publishedDate;
return a > b ? -1 : a<b ? 1 : 0;
});
return articles;
修改以澄清:
这是当前的数据库结构。 article
集合中的每个articles
都如下所示:
{
"_id" : "CdHWxgq75yjcgQoDZ",
"category" : "Nyheter",
"tags" : [
"ZaifTyGGouPwdrGur"
],
"data" : [
"Hello this is some random content"
],
"publishedOnSites" : [
"ZaifTyGGouPwdrGur"
],
"publishedDate" : ISODate("2015-11-20T07:22:09.799Z"),
"userId" : "B3t6QFgG7MfNkvzR5"
}
website
集合中的每个websites
都是这样的:
{
"_id" : "ZaifTyGGouPwdrGur",
"name" : "SITENAME",
"categories" : [
"News",
"Life",
"TV",
"Sport",
"Quizzes",
"Video"
],
"tags" : [
"batman",
"bil",
"polis",
"flicka",
"cool",
"byrå",
"förvandling"
],
"articles" : [
"PgGetxkC9KynaPNLc",
"ZaifTyGGouPwdrGur",
"oPQHh3u2CGhRwYp2a",
"a5ZkhbxRcLEpggTuF",
"t3n8Zp6Cve6e88Gmt",
"eYQmaavt6tAwbbmzf",
"F9LzZFcFxSpejseHn",
"NLWb5NahoPjgAt7eN",
"pwkTtFN8gZCsnKDGg",
"o62uCK7S6qauJfyYa",
"pivJGzo4CFw3QRb3v",
"H2EHv7rX5GQmyqiDk",
"tGfrv82NMwJEpuThK",
"CvjGPKmsCqmd9o5oP",
"29hoZxnmfovTnC8TM",
"NXHXhaXDYgKLagamJ",
"9EjfABeK5akDLeZJT",
"5q5zeYRkPHMJXtEpT",
"eWGwWq3J7JqtQi2fK",
"7W27ufZ4qDyX4mJnC",
"oBhGpNCBTrMcb3qvq",
"7pRorBYbZ8Mx6jYX3",
"d2PoAFGTcbQzapXpW",
"qDRiB65vcpMu6KTTe",
]
}
我将文章ID保存在每个网站中,以便快速获取,而无需过滤所有文章。然而,当我想进行诸如排序日期,限制,跳过第一个元素,仅获取具有特定类别的文章等查询时,这就成了一个问题。
我需要有关更好的数据库结构的建议。
答案 0 :(得分:1)
通常情况下,让MongoDB处理过滤,排序等更好。它知道如何做得好以及如何快速完成。
所以,你想要做的是:
var arcticles_ids = Websites.findOne({name: "SITENAME"}).articles;
var articlesCursor = Articles.find({_id: {$in: articles_ids}}, {sort: {publishedDate: -1}});
在第二行,您可以添加限制等。如果您担心性能,请添加indexes,例如:
db.articles.createIndex({_id: 1, publishedDate: -1});
注意:不要只需将此索引添加到数据库中。分析您拥有的查询类型,并根据该查询添加索引。以上只是一个例子。
此外,您可能需要考虑在Articles
集合中添加一个字段,该集合存储本文所属的所有网站。 E.g:
article: {
someField: someValue,
websites_ids: [1, 5, 8, 10]
}
如果您想让查询具有反应性,这非常有用。 E.g:
var articlesCursor = Articles.find({websites_ids: website_id}, {sort: {publishedDate: -1}});
这样,如果光标处于被动状态并且文章被添加到网站,则客户端会立即收到有关该文章的此信息。如果按照您的方式完成,光标将仅跟踪文章的特定ID。需要考虑的事情。