1

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

马特

我已尝试实施您对分面搜索的建议,但我似乎无法弄清楚如何使用用户 ID 的子集执行选择。我创建的索引如下

   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 };
    }
   }

我有一个 UserId 列表,我想在针对它运行方面之前使用它来缩小此选择范围,但我尝试过的方法都不想编译。你能告诉我 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

我希望你能指出我如何实现这一目标的正确方向。

另外,感谢您在 Faceted Search 方面所做的工作。这似乎是我正在寻找的执行大量我需要在 RavenDB 中运行的查询。干杯!

-- 编辑 #2 --

这是我用来实现我想要的结果的 SQL 表达式。

SELECT t.Tag, COUNT(*) FROM UserTags t WHERE t.UserID in ('1', '2', '3', '4', '5') GROUP BY t.Tag
4

2 回答 2

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) };    
    }
}

当然,您需要一个条件将其限制为某个“部分”。

于 2012-04-16T02:02:25.720 回答
1

另一种方法是使用分面搜索并从中获取计数。它比 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");

看看这个代码示例,它展示了如何实现您的确切场景。

于 2012-04-16T08:45:16.167 回答