采用以下模型:
一个问题(比如,一个堆栈问题!)
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)
这是最强大的方法。我调查了以下内容。
聚合框架。 这使我能够计算出Object表中出现的ObjectId的次数,但我没有简单的方法来获取标记的名称。我想我必须做另一个数据库调用,获取所有标签然后将它们映射在一起。
在标签表上有COUNT,每次我提交问题检查以查看是否已添加或删除标签,然后递增或递减此计数器。我似乎无法让我的大脑接受这是一个很好的方法来做到这一点。
[编辑 - 见评论]
人们会推荐哪些(以及为什么)。有没有我错过的策略?
我正在使用C#的mongo驱动程序
答案 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()
}