实例从文本标签列表开始计算

时间:2012-04-16 00:58:09

标签: asp.net-mvc count ravendb

我正在使用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

2 个答案:

答案 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,它展示了如何实现您的确切方案。