2

采取以下模型:

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

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. 聚合框架。这使我能够计算 ObjectId 在 Question 表中出现的次数,但我没有简单的方法来获取标签的名称。我想我将不得不进行另一个数据库调用,获取所有标签然后将它们映射在一起。

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

[编辑-见评论]

  1. 在问题中存储标签名称。使用标签名称为 Id。这将使#1 工作得更好。但是标签名称可能会改变,所以我想这会产生连锁反应。

人们会推荐其中哪些(以及为什么)。有没有我错过的策略?

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

4

2 回答 2

2

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

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

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

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

于 2013-05-25T16:07:22.833 回答
1

您可以对 mongo 进行 2 次查询以获取每个集合的 C# 列表。

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

然后对这些 C# 集合进行内存中的 linq 查询,并返回一个仅包含您想要的属性的自定义对象(包括问题计数)。例如

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()
}
于 2013-05-28T09:22:51.343 回答