参考多个网站中的相同文档

时间:2015-11-29 08:45:37

标签: mongodb meteor database

我有一个管理界面网站,用户可以在其中创建新闻文章,也可以选择本文应出现在哪些网站上。 (有许多网站连接到同一个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保存在每个网站中,以便快速获取,而无需过滤所有文章。然而,当我想进行诸如排序日期,限制,跳过第一个元素,仅获取具有特定类别的文章等查询时,这就成了一个问题。

我需要有关更好的数据库结构的建议。

1 个答案:

答案 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。需要考虑的事情。