I'm porting some generic tagging code from NHibernate, and i'm trying to figure out how to implement "related tags". IOW, find related items based on a set of common tags.
Abbreviated model follows :
public class Vocabulary { public long Id {get; set;} public string Name {get; set;}
}
public class Term { public long Id {get; set;} public string Name {get; set;} public long VocabularyId {get; set;}
}
[Serializable] public class TaggedItem : DomainEntity { private DateTime _taggedDate; public TaggedItem() { _taggedDate = SystemTime.Now(); } public TaggedItem(Type itemType, string itemId, DateTime taggedDate, Term tag, Person taggedBy) { ItemType = itemType; ItemId = itemId; TaggedDate = taggedDate.EnsureUtc(); TermId = tag.Id; TaggedById = taggedBy.Id; } public DateTime TaggedDate { get { return _taggedDate; } set { _taggedDate = value.EnsureUtc(); } } public Type ItemType { get; set; } // Raven Id of item being tagged public string ItemId { get; set; } public long TermId { get; set; } public long TaggedById { get; set; } }
What i need is that given a list of term names (forget vocabulary for now), give me a set of TaggedItems that were tagged with those terms, but exclude those terms from the result. So suppose i have a Albums as follows : Album1 - tagged with "rock", "punk" Album2 - "jazz", "vocals" Album3 - "punk", "rock", "jazz"
If i search related items for {"punk", "rock"}, i should get tagged items document for Album3
In NHibernate, i built this with the criteria API, which was involved there even given its sophistication.
Any clues on 1. How to setup an index to handle this efficiently 2. How to build the query. In NH, i used multiple self-joins. I dont think raven handles this
On Sat, Jun 30, 2012 at 8:04 AM, clayton collie <gbo...@gmail.com> wrote:
> I'm porting some generic tagging code from NHibernate, and i'm trying to
> figure out how to implement "related tags".
> IOW, find related items based on a set of common tags.
> Abbreviated model follows :
> public class Vocabulary
> {
> public long Id {get; set;}
> public string Name {get; set;}
> }
> public class Term
> {
> public long Id {get; set;}
> public string Name {get; set;}
> public long VocabularyId {get; set;}
> }
> [Serializable]
> public class TaggedItem : DomainEntity
> {
> private DateTime _taggedDate;
> public TaggedItem()
> {
> _taggedDate = SystemTime.Now();
> }
> public TaggedItem(Type itemType, string itemId, DateTime
> taggedDate, Term tag, Person taggedBy)
> {
> ItemType = itemType;
> ItemId = itemId;
> TaggedDate = taggedDate.EnsureUtc();
> TermId = tag.Id;
> TaggedById = taggedBy.Id;
> }
> public DateTime TaggedDate
> {
> get { return _taggedDate; }
> set { _taggedDate = value.EnsureUtc(); }
> }
> public Type ItemType { get; set; }
> // Raven Id of item being tagged
> public string ItemId { get; set; }
> public long TermId { get; set; }
> public long TaggedById { get; set; }
> }
> What i need is that given a list of term names (forget vocabulary for
> now), give me a set of TaggedItems that were tagged with those terms, but
> exclude those terms from the result. So suppose i have
> a Albums as follows :
> Album1 - tagged with "rock", "punk"
> Album2 - "jazz", "vocals"
> Album3 - "punk", "rock", "jazz"
> If i search related items for {"punk", "rock"}, i should get tagged items
> document for Album3
> In NHibernate, i built this with the criteria API, which was involved
> there even given its sophistication.
> Any clues on
> 1. How to setup an index to handle this efficiently
> 2. How to build the query. In NH, i used multiple self-joins. I dont think
> raven handles this
Independent tag occurrences allow me to show individual personal preferences (for recommendations) as well as showing site-wide popularity of tags over time. It allows for tagging orthogonal to the domain, i.e. i can tag any document in the system without including tags in individual documents.
And if you want to get back a mixed bag of DomainEntity objects:
Somewhat. The clearest way i can express the question is: Given a set of "tagging occurrences'(TaggedItem in my case), how do I query for the set of these which have a superset of tags in a given list.
i've created an index (TaggedItem_Index) which includes the TermName in addition to the fields of TaggedItem.
> What i need is that given a list of term names (forget vocabulary for >> now), give me a set of TaggedItems that were tagged with those terms, but >> exclude those terms from the result. So suppose i have >> a Albums as follows : >> Album1 - tagged with "rock", "punk" >> Album2 - "jazz", "vocals" >> Album3 - "punk", "rock", "jazz"
>> If i search related items for {"punk", "rock"}, i should get tagged items >> document for Album3
>> In NHibernate, i built this with the criteria API, which was involved >> there even given its sophistication.
>> Any clues on >> 1. How to setup an index to handle this efficiently >> 2. How to build the query. In NH, i used multiple self-joins. I dont >> think raven handles this
> Independent tag occurrences allow me to show individual personal
> preferences (for recommendations)
> as well as showing site-wide popularity of tags over time. It allows for
> tagging orthogonal to the domain, i.e.
> i can tag any document in the system without including tags in individual
> documents.
> Somewhat. The clearest way i can express the question is: Given a set of
> "tagging occurrences'(TaggedItem in my case), how do I query for the set of
> these
> which have a superset of tags in a given list.
> i've created an index (TaggedItem_Index) which includes the TermName in
> addition to the fields of TaggedItem.
>> What i need is that given a list of term names (forget vocabulary for
>>> now), give me a set of TaggedItems that were tagged with those terms, but
>>> exclude those terms from the result. So suppose i have
>>> a Albums as follows :
>>> Album1 - tagged with "rock", "punk"
>>> Album2 - "jazz", "vocals"
>>> Album3 - "punk", "rock", "jazz"
>>> If i search related items for {"punk", "rock"}, i should get tagged
>>> items document for Album3
>>> In NHibernate, i built this with the criteria API, which was involved
>>> there even given its sophistication.
>>> Any clues on
>>> 1. How to setup an index to handle this efficiently
>>> 2. How to build the query. In NH, i used multiple self-joins. I dont
>>> think raven handles this
I'm creating a generic tagging system, where "tagging occurrences" are stored as docs outside of individual models. When a user tags a document, one of these documents is created.
So lets say i have an Event, tagged with "jazz", "music", "adult". On the event page, i want to allow the user to find related events (documents) based on those tags. Essentially, find all other documents which have those tags in common.
So suppose i have Events (concerts in this example):
>> Independent tag occurrences allow me to show individual personal >> preferences (for recommendations) >> as well as showing site-wide popularity of tags over time. It allows for >> tagging orthogonal to the domain, i.e. >> i can tag any document in the system without including tags in individual >> documents.
>> Somewhat. The clearest way i can express the question is: Given a set of >> "tagging occurrences'(TaggedItem in my case), how do I query for the set of >> these >> which have a superset of tags in a given list.
>> i've created an index (TaggedItem_Index) which includes the TermName in >> addition to the fields of TaggedItem.
>>> What i need is that given a list of term names (forget vocabulary for >>>> now), give me a set of TaggedItems that were tagged with those terms, but >>>> exclude those terms from the result. So suppose i have >>>> a Albums as follows : >>>> Album1 - tagged with "rock", "punk" >>>> Album2 - "jazz", "vocals" >>>> Album3 - "punk", "rock", "jazz"
>>>> If i search related items for {"punk", "rock"}, i should get tagged >>>> items document for Album3
>>>> In NHibernate, i built this with the criteria API, which was involved >>>> there even given its sophistication.
>>>> Any clues on >>>> 1. How to setup an index to handle this efficiently >>>> 2. How to build the query. In NH, i used multiple self-joins. I dont >>>> think raven handles this
You are still describing the scenario in relational terms
What you want to do is have a list of strings in your classes, which will
contain the tag names. When you click on Related, you simply issue a query
to RavenDB asking it to find all documents with at least the tags the
currently viewed document has.
On Sat, Jun 30, 2012 at 8:54 PM, clayton collie <gbo...@gmail.com> wrote:
> I'm creating a generic tagging system, where "tagging occurrences" are
> stored as docs outside of individual models. When a user tags a document,
> one of these documents is created.
> So lets say i have an Event, tagged with "jazz", "music", "adult". On the
> event page, i want to allow the user to find related events (documents)
> based on those tags. Essentially, find all other
> documents which have those tags in common.
> So suppose i have Events (concerts in this example):
>>> Independent tag occurrences allow me to show individual personal
>>> preferences (for recommendations)
>>> as well as showing site-wide popularity of tags over time. It allows for
>>> tagging orthogonal to the domain, i.e.
>>> i can tag any document in the system without including tags in
>>> individual documents.
>>> Somewhat. The clearest way i can express the question is: Given a set of
>>> "tagging occurrences'(TaggedItem in my case), how do I query for the set of
>>> these
>>> which have a superset of tags in a given list.
>>> i've created an index (TaggedItem_Index) which includes the TermName in
>>> addition to the fields of TaggedItem.
>>>> What i need is that given a list of term names (forget vocabulary for
>>>>> now), give me a set of TaggedItems that were tagged with those terms, but
>>>>> exclude those terms from the result. So suppose i have
>>>>> a Albums as follows :
>>>>> Album1 - tagged with "rock", "punk"
>>>>> Album2 - "jazz", "vocals"
>>>>> Album3 - "punk", "rock", "jazz"
>>>>> If i search related items for {"punk", "rock"}, i should get tagged
>>>>> items document for Album3
>>>>> In NHibernate, i built this with the criteria API, which was involved
>>>>> there even given its sophistication.
>>>>> Any clues on
>>>>> 1. How to setup an index to handle this efficiently
>>>>> 2. How to build the query. In NH, i used multiple self-joins. I dont
>>>>> think raven handles this
On Saturday, June 30, 2012 2:05:40 PM UTC-4, Itamar Syn-Hershko wrote:
> You are still describing the scenario in relational terms
> What you want to do is have a list of strings in your classes, which will > contain the tag names. When you click on Related, you simply issue a query > to RavenDB asking it to find all documents with at least the tags the > currently viewed document has.
Strings would be ids, but thats certainly a way to go. My only difficulties 1. Terms have identity ("set" has a different meaning if 'im talking math, music or sports) - hence ids and not strings. 2. I want to know who tagged what and when 2. I want to do this once, as a service, so i dont need have ids in each document i want to tag. In my app, there are many such document types.
I'll try the embedded case and see if a general pattern emerges.
1) So use ids.
2) So use a complex relation (Entity.Tags where Tags contains object with
(TagId, TaggedBy, TaggedWhen).
3) You can do as a base class collection, but I don't think you need a
service for that. It is just data, and easily used
On Sat, Jun 30, 2012 at 9:13 PM, clayton collie <gbo...@gmail.com> wrote:
> On Saturday, June 30, 2012 2:05:40 PM UTC-4, Itamar Syn-Hershko wrote:
>> You are still describing the scenario in relational terms
>> What you want to do is have a list of strings in your classes, which will
>> contain the tag names. When you click on Related, you simply issue a query
>> to RavenDB asking it to find all documents with at least the tags the
>> currently viewed document has.
> Strings would be ids, but thats certainly a way to go. My only difficulties
> 1. Terms have identity ("set" has a different meaning if 'im talking
> math, music or sports) - hence ids and not strings.
> 2. I want to know who tagged what and when
> 2. I want to do this once, as a service, so i dont need have ids in each
> document i want to tag. In my app, there are many such document types.
> I'll try the embedded case and see if a general pattern emerges.
aye...@ayende.com> wrote:
> 1) So use ids.
> 2) So use a complex relation (Entity.Tags where Tags contains object with
> (TagId, TaggedBy, TaggedWhen).
> 3) You can do as a base class collection, but I don't think you need a
> service for that. It is just data, and easily used
> On Sat, Jun 30, 2012 at 9:13 PM, clayton collie <gbo...@gmail.com> wrote:
>> On Saturday, June 30, 2012 2:05:40 PM UTC-4, Itamar Syn-Hershko wrote:
>>> You are still describing the scenario in relational terms
>>> What you want to do is have a list of strings in your classes, which
>>> will contain the tag names. When you click on Related, you simply issue a
>>> query to RavenDB asking it to find all documents with at least the tags the
>>> currently viewed document has.
>> Strings would be ids, but thats certainly a way to go. My only
>> difficulties
>> 1. Terms have identity ("set" has a different meaning if 'im talking
>> math, music or sports) - hence ids and not strings.
>> 2. I want to know who tagged what and when
>> 2. I want to do this once, as a service, so i dont need have ids in each
>> document i want to tag. In my app, there are many such document types.
>> I'll try the embedded case and see if a general pattern emerges.
For the case of multiple document types having tags, an ITaggable interface (with a Tags collection property) may be sufficient to hack a general solution.
> On Sat, Jun 30, 2012 at 10:38 PM, Oren Eini (Ayende Rahien) < > aye...@ayende.com> wrote:
>> 1) So use ids. >> 2) So use a complex relation (Entity.Tags where Tags contains object with >> (TagId, TaggedBy, TaggedWhen). >> 3) You can do as a base class collection, but I don't think you need a >> service for that. It is just data, and easily used
>> On Sat, Jun 30, 2012 at 9:13 PM, clayton collie wrote:
>>> On Saturday, June 30, 2012 2:05:40 PM UTC-4, Itamar Syn-Hershko wrote:
>>>> You are still describing the scenario in relational terms
>>>> What you want to do is have a list of strings in your classes, which >>>> will contain the tag names. When you click on Related, you simply issue a >>>> query to RavenDB asking it to find all documents with at least the tags the >>>> currently viewed document has.
>>> Strings would be ids, but thats certainly a way to go. My only >>> difficulties >>> 1. Terms have identity ("set" has a different meaning if 'im talking >>> math, music or sports) - hence ids and not strings. >>> 2. I want to know who tagged what and when >>> 2. I want to do this once, as a service, so i dont need have ids in each >>> document i want to tag. In my app, there are many such document types.
>>> I'll try the embedded case and see if a general pattern emerges.
@Clayton - here's a demo app i have up on github<https://github.com/PureKrome/RavenOverflow>. It lists questions. U can filter the question list, by tags. This is the equivalent of saying 'gimme all the Events that are tagged as 'jazz' '
Now i know it's not -exactly- what you're after, but it's a start. It's not too hard to replace my Tag property with something more to your requirements.
On Monday, July 2, 2012 11:41:27 PM UTC-4, Justin A wrote:
> @Clayton - here's a demo app i have up on github<https://github.com/PureKrome/RavenOverflow>. > It lists questions. U can filter the question list, by tags. This is the > equivalent of saying 'gimme all the Events that are tagged as 'jazz' '
> Now i know it's not -exactly- what you're after, but it's a start. It's > not too hard to replace my Tag property with something more to your > requirements.