MongoDB计算在另一个表中引用项的次数

时间:2013-05-25 13:58:54

标签: c# asp.net-mvc mongodb

采用以下模型:

一个问题(比如,一个堆栈问题!)

Question {
    _id : ObjectId(123),
    Question : "MongoDB: Count number of referenced items",
    Tags : [ObjectId(1), ObjectId(2), ObjectId(3)] 
}

标签表

Tag{
    _id : ObjectId(1),
    tag : "MongoDB",
    description : "stuff"
},
{
 .... more tags
}

我想列出所有标签,每个标签旁边都会显示该标签使用次数的计数。然后,您可以单击标签进行编辑,如下所示:

MongoDB (1232)
C# (23232)

这是最强大的方法。我调查了以下内容。

  1. 聚合框架。 这使我能够计算出Object表中出现的ObjectId的次数,但我没有简单的方法来获取标记的名称。我想我必须做另一个数据库调用,获取所有标签然后将它们映射在一起。

  2. 在标签表上有COUNT,每次我提交问题检查以查看是否已添加或删除标签,然后递增或递减此计数器。我似乎无法让我的大脑接受这是一个很好的方法来做到这一点。

  3. [编辑 - 见评论]

    1. 在标题中存储标记名称。使用标记名称为Id。这将使#1更好地工作。标签名称可能会改变,所以我猜这有连锁反应。
    2. 人们会推荐哪些(以及为什么)。有没有我错过的策略?

      我正在使用C#的mongo驱动程序

2 个答案:

答案 0 :(得分:2)

考虑到系统的有限视图,我能想到的最有效的方法是将标签名称保存在集合中,而不是ObjectId。这样做的好处是你的group by / count将是一个单独的聚合操作,我不明白为什么ObjectId将是一个比名称更好的标记标识符(假设名称是唯一的)

缺点是标签的重命名将是两部分操作而不是一部分操作。您必须先在tags表中重命名它,然后使用类似的内容在所有questions数组的Tags表中重命名它。

db.questions.update({'Tags':"Old Name"},{$set:{'Tags.$':'New Name'}})

鉴于计数可能是一个更频繁的操作,我会说在一次调用MongoDB时执行该操作,同时将重命名增加到两个单独的操作应该是明确的净增益。

答案 1 :(得分:1)

您可以向mongo发出2个查询以获取每个集合的C#列表。

List<Question> questions = YourGetQuestionListFunction();
List<Tag> tags = YourGetTagListFunction();

然后在这些C#集合中创建内存linq查询,并返回仅包含所需属性的自定义对象(包括问题计数)。 e.g。

var result = from t in tags
select new {
TagId = t._id,
TagName = t.tag,
Description = t.description,
QuestionCount = questions.Where(x => x.Tags != null && x.Tags.Contains(t.Id)).Count()
}