我正在使用RavenDB并允许用户在数据库中输入项目,以便将文本标签关联起来。该项的类是
public class TagItem
{
public string Id { get; set; }
public string UserId { get; set; }
public List<string> Tags { get; set;}
public DateTime DateCreated { get; set; }
}
}
我想要做的是获取文档查询中选定项目中每个单独标记的实例计数。例如
Bacon : 12
Fudge : 8
Marshmallow : 6
我目前正在通过迭代项目并递增每个标记的计数来做到这一点,但它似乎不是一种非常优雅的方式来获得结果。我想知道是否有人建议更好的方法来实现这一目标?提前谢谢。
- 编辑#1 -
马特
我试图实现您对分面搜索的建议,但我似乎无法弄清楚如何使用userID的子集执行选择。我已将索引创建为以下
public class Tag_Facets : AbstractIndexCreationTask<UserModel>
{
public Tag_Facets()
{
Map = locations => from user in users
from tag in user.Tags
select new { Tag = tag.ToString().ToLower(), user.Id };
}
}
我有一个UserIds列表,我想用它来缩小这个选择,然后再运行facet,但是我尝试过的方法都没有想要编译。你能否让我知道Where子句的含义是什么?
我的FacetSetup如下
this.DocumentSession.Store(new FacetSetup { Id = "facets/TagFacets", Facets = new
List<Facet> { new Facet { Name = "Tag" } } });
我正在尝试构建的查询是
var facetResults = this.DocumentSession.Query<LocationModel>("Tag/Facets")
.Where(x => x.Id.Contains(new List<string> { "1", "2", "3" }))
.ToFacets("facets/TagFacets");
将无法生成,因为Contains不接受List
我希望你能指出我如何做到这一点的正确方向。
另外,感谢您在分面搜索方面的工作。这似乎是我正在寻找执行我需要在RavenDB中运行的许多查询。干杯!
- 编辑#2 -
这是我用来实现我想要的结果的SQL表达式。
SELECT t.Tag, COUNT(*) FROM UserTags t WHERE t.UserID in ('1', '2', '3', '4', '5') GROUP BY t.Tag
答案 0 :(得分:2)
如果您需要按标签名称分组的标签计数,RavenDB网站已经有一个示例:
http://ravendb.net/kb/2/creating-a-tag-cloud
略微修改指数:
public class Tags_Count : AbstractIndexCreationTask<Post, Tags_Count.ReduceResult>
{
public class ReduceResult
{
public string Name { get; set; }
public int Count { get; set; }
}
public Tags_Count()
{
Map = posts => from post in posts
from tag in post.Tags
select new { Name = tag.ToString().ToLower(), Count = 1 };
Reduce = results => from tagCount in results
group tagCount by tagCount.Name
into g
select new {Name = g.Key, Count = g.Sum(x => x.Count) };
}
}
当然,您需要一个条件将其限制为某个“部分”。
答案 1 :(得分:1)
另一种方法是使用faceted search并从中获取计数。它比Map / Reduce更灵活,因为它允许您在获得计数时指定查询。
给出这样的指数:
from question in docs
from tag in question.Tags
select new
{
question.CreatedOn,
Tag = tag
}
然后你可以像这样定义构面范围(使用默认行为,它将为你寻找每个唯一的术语)
var facetSetupDoc = new FacetSetup
{
Id = "facets/TagFacets",
Facets = new List<Facet> { new Facet {Name = "Tag"} }
}
最后你这样查询:
var facetResults = s.Query<Question>("QuestionTags")
.Where(x => x.CreatedOn >= new DateTime(2008, 5, 20))
.ToFacets("facets/TagFacets");
看看这个code sample,它展示了如何实现您的确切方案。