I am using RavenDB and allowing a user to enter an item into the database with which they can associate textual tags. The class for the item is
public class TagItem
{
public string Id { get; set; }
public string UserId { get; set; }
public List<string> Tags { get; set;}
public DateTime DateCreated { get; set; }
}
}
What i would like to do is get an instance count for each individual tag in a selection of items from the document query. For instance
Bacon : 12
Fudge : 8
Marshmallow : 6
I am currently doing this by iterating through the items and incrementing the count for each tag but it doesn’t seem to be a very elegant way of obtaining the results. I was wondering if anyone had a suggestion for a better way to achieve this? Thanks in advance.
— EDIT #1 —
Matt
I have tried to implement your suggestion of faceted search but I cant seem to figure out how to perform a selection using a subset of userIDs. I have created the index as the following
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 };
}
}
I have a List of UserIds that I would like to use to narrow this selection down before running the facet against it but none of the methods that I have tried want to compile. Can you provide me with an idea of what the Where clause would look like for this?
My FacetSetup is as follows
this.DocumentSession.Store(new FacetSetup { Id = "facets/TagFacets", Facets = new
List<Facet> { new Facet { Name = "Tag" } } });
The query that i am trying to build is
var facetResults = this.DocumentSession.Query<LocationModel>("Tag/Facets")
.Where(x => x.Id.Contains(new List<string> { "1", "2", "3" }))
.ToFacets("facets/TagFacets");
which will not build because Contains doesn’t accept List
I was hoping that you might be able to point me in the right direction on how I might accomplish this.
Also, thank you for your work on Faceted Search. It seems to be what I’m looking for to perform a lot of the queries that I need to run in RavenDB. Cheers!
— EDIT #2 —
This is the SQL expression that I would use to achieve the results that I wanted.
SELECT t.Tag, COUNT(*) FROM UserTags t WHERE t.UserID in ('1', '2', '3', '4', '5') GROUP BY t.Tag
Another approach is to use faceted search and get the counts from that. It’s a little bit more flexible than Map/Reduce as it allows you to specify a query when you get the counts.
Given an index like this:
You then define the facet ranges like this (using the default behaviour, which will look for every unique term for you)
Finally you query it like this:
Take a look at this code sample, it shows how to implement your exact scenario.