如何查询所有子文档 [英] How to query all subdocuments

查看:96
本文介绍了如何查询所有子文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从MongoDb和nodejs(使用猫鼬)开始.

I'm beginning with MongoDb and nodejs (using mongoose).

我有一个故事的集合,每个故事都可以有一个或多个标签,就像这样:

I have a collection of Stories, each of them can have one or more Tags, it's something like that:

{
    title: "The red fox",
    content: "The red fox jumps away...",
    tags: [
        {
            tagname: "fairytale",
            user: "pippo"
        },
        {
            tagname: "funny",
            user: "pluto"
        },
        {
            tagname: "fox",
            user: "paperino"
        }
    ]
},

... other stories

现在,我想制作一个标签云.

这意味着查询所有标签的故事.

It means querying Stories for all tags.

在关系世界(例如MySQL)中,我会有一个Stories表,一个Tag表和一个Stories_Tags表(多对多).然后,我要查询标签表或类似的内容.

In a relational world (e.g. MySQL) I would have a Stories table, a Tags table and a Stories_Tags table (many-to-many). Then I'd query on the tags table or something like that.

有办法吗? (我确定是的)

Is there a way to do so? (I'm sure yes)

如果是,这是一个好习惯吗?还是打破了nosql范式?

If yes, is it a good practice? Or does it break the nosql paradigm?

您能想象出一种更好的方案设计方法吗?

Can you imagine a better way for my schema design?

推荐答案

您可以使用MR来完成此任务.在MR中,您只需选择标签并投影它们:

You can use an MR to accomplish this. In an MR you would simply pick out the tags and project them:

var map = function(){
     for(var i=0;i<this.tags.length;i++){
         emit(this.tags[i].tagname, {count: 1});
     }
}

然后您的reduce将会遍历所发出的文档,基本上总结了看到该标签的次数.

And then your reduce would run through the emitted documents basically summing up the amount of times that tag was seen.

如果升级到最新的不稳定版本2.2,则也可以使用聚合框架.您将使用聚合框架的$ project和$ sum样条线将标签投射到每个帖子中,然后对其进行汇总,以创建基于分数的标签云,从而允许您根据汇总来调整每个标签的文本大小. >

If you upgrade to the lastest unstable 2.2 you can also use the aggregation framework. You would use the $project and $sum piplines of the aggregation framework to project the tags out of each post and then summing them up to create a score based tag cloud allowing you size the text of each tag based upon the summing.

如果是,这是一个好习惯吗?还是打破了nosql范式?

If yes, is it a good practice? Or does it break the nosql paradigm?

这是MongoDB中的一个非常标准的问题,您将无法解决.随着可重用结构的出现,不可避免地需要对它进行一些复杂的查询.幸运的是,在2.2中存在要保存的aggregationm框架.

This is a pretty standard problem in MongoDB and one you won't get away from. With the reusable structure comes the inevitable need to do some complex querying over it. Fortunately in 2.2 there is the aggregationm framework to save.

关于这是好方法还是坏方法,这是一个非常标准的方法,因此它既不是好事也不是坏事.

As to whether this is a good or bad approach, it is a pretty standard one as such it is neither good or bad.

要使结构更好,您可以将唯一标记及其数量预先汇总到一个单独的集合中.这样可以更轻松地实时构建标签云.

As to making the structure better, you could pre-aggregate unique tags with their count to a separate collection. This would make it easier to build your tag cloud in realtime.

预聚合是一种创建其他集合的形式,通常不需要使用MR或聚合框架就可以从MR获得其他集合.通常这是基于您的应用的事件,因此,当用户创建帖子或为帖子加标签时,它将触发预聚集事件到"tag_count"的集合,如下所示:

Pre-aggregation is a form of creating the other collection you would normally get from an MR without the need to use MRs or the aggregation framework. It is normally event based upon your app, so when a user create a post or retags a post it will trigger a pre-aggregation event to a collection of "tag_count" which looks like:

{
    _id: {},
    tagname: "",
    count: 1
}

触发事件后,您的应用将遍历帖子上的标签,基本上会像这样进行$ inc upserts:

When the event is triggered your app will loop through the tags on the post basically doing $inc upserts like so:

db.tag_count.update({tagname: 'whoop'}, {$inc: {count: 1}}, true);

因此,您现在将在整个博客中拥有一个带有标签计数的标签集合.从那里开始,您将沿着与MR相同的路线前进,只是查询此集合以获取您的数据.当然,您需要处理删除和更新事件,但是您已经有了大致的了解.

And so you will now have a collection of tags with their count throughout your blog. From there you go the same route as the MR did and just query this collection getting out your data. You would of course need to handle deletion and update events but you get the general idea.

这篇关于如何查询所有子文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆