-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: [Hibernate Search] Property/Field Bridges for M:M Collection
PostPosted: Mon Nov 19, 2007 6:45 pm 
Regular
Regular

Joined: Fri Oct 05, 2007 1:17 pm
Posts: 78
I have a unidirectional M:M relationship between two entities. Let's call them Item and KeyWord. Each is represented by a table, and 1 Item has many KeyWords while a KeyWord can be applied to more than 1 item.

Here is how things look in my Item class:


Code:
@ManyToMany
@JoinTable(name = "ITEM_KEY_WORD_JOIN",
              joinColumns = {@JoinColumn(name = "ITEM_ID", nullable = false)},
              inverseJoinColumns = {@JoinColumn(name = "KEYWORD_ID", nullable = false)})
   public Set<KeyWord> getKeyWords() {
      return keyWords;
   }



Not surprisingly, users may want to search for Items based on KeyWords. My question is simply how to accomplish this. Do I place an Index annotation here that looks like @Field(index = Index.TOKENIZED, store = Store.NO)? Or do I place an annotation on the KeyWord class?

Moreover, how do I implement the Property/Field Bridge in this case? The KeyWord class has toString implemented to make for a fairly trivial implementation of the objectToString method in the StringBridge interface.

Any insight is appreciated.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 21, 2007 11:15 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Check the documentation for @IndexedEmbedded, I think it does what you want.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 23, 2007 7:49 pm 
Regular
Regular

Joined: Fri Oct 05, 2007 1:17 pm
Posts: 78
I tried the same approach I used for my 1:M association with my M:M association. Something is wrong though since I don't see much in the index directory, and Luke tells me the index is corrupted.

Given that 1 Item can have many KeyWords and that 1 KeyWord can apply to multiple Items, here is my setup in the owning class Item:

Code:
@ManyToMany
   @JoinTable(name = "ITEM_KEY_WORD_JOIN",
              joinColumns = {@JoinColumn(name = "ITEM_ID", nullable = false)},
              inverseJoinColumns = {@JoinColumn(name = "KEYWORD_ID", nullable = false)})
   @IndexedEmbedded
   public Set<KeyWord> getKeyWords() {
      return keyWords;
   }


And here is the setup in the KeyWord class:

Code:
@Column(name = "NAME", nullable = false, unique = true)
   @Field(index = Index.UN_TOKENIZED, store = Store.NO)
   @Boost(3f)
   public String getName() {
      return name;
   }


The association is unidirectional. Item has a collection of KeyWords, but KeyWord is unaware of the Items it has been applied to.

Please let me know if I need to do more elaborate things (like a FieldBridge) when dealing with a collection class in the owning class Item.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 24, 2007 2:54 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Well if your index is corrupted, it has nothing to do with your mapping. You have other problems :)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 24, 2007 3:55 pm 
Regular
Regular

Joined: Fri Oct 05, 2007 1:17 pm
Posts: 78
Well gee thanks! ;)

I have been indexing everything the same way as before--in the @BeforeSuite method of my TestNG tests and using the same code. Since things turned out all wacky, I wasn't sure if applying the same annotations to a Set (as opposed to a non-Collection object) was somehow improper, and I didn't see any ManyToMany examples in the documentation.

OK, well I will re-index on Monday and see what happens.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 26, 2007 4:15 pm 
Regular
Regular

Joined: Fri Oct 05, 2007 1:17 pm
Posts: 78
I am not sure if I was mistaken the other day or what I did to fix things, but the index of my key words is working just fine. According to Luke, I have the following excerpt in the Overview tab when I filter just on keyWords.name:

<keywords.name> aluminum

However, when I run a test with this query

+keywords.name:Aluminum~0.4

I get no hits when there should be 5.

On the Search tab in Luke, I apply the same query, and I get all the right hits. What is curious perhaps is that there are columns for _hibernate_class, keyWords.id, keyWords.name among others, but the keyWords.name column is empty while the keyWords.id column is populated with space-delimited IDs from the KEY_WORD table.

Now since I know so little about Lucene and even less about Luke, I don't know if that is even relevant, but I thought I would mention it just in case.

Please let me know if my query or my index is flawed here...or if I can provide further information.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 26, 2007 5:21 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
neilac333 wrote:
+keywords.name:Aluminum~0.4

I get no hits when there should be 5.


I suggest you check your analyzer, it is probably different between luke and your code.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 26, 2007 6:55 pm 
Regular
Regular

Joined: Fri Oct 05, 2007 1:17 pm
Posts: 78
I just double checked, but I am using the StandardAnalyzer for both the index and within Luke. Luke actually returns an extra sixth item with "Ammonium" in it since I have a fuzzy factor of 0.4 applied to "Aluminum." That is fine with me.

But my tests with +keywords.name:Aluminum~0.4 return zip.

Is this how the query should look given that the Item class has a getKeyWords() method that returns a Set of KeyWords, each of which has a getName() method?

Meanwhile I will be looking to see if I am doing anything silly.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 28, 2007 5:00 am 
Newbie

Joined: Mon Nov 06, 2006 10:22 am
Posts: 2
It indeed must be silly. Try tokenizing the field for search. And also, if you want that to appear in luke, you gotta store it.

Quote:
@Field(index = Index.UN_TOKENIZED, store = Store.NO)


Instead try

@Field(index = Index.TOKENIZED, store = Store.YES)

As I understand, your usecase doesnt require that you store the keyword. Yet, if you want to see that through luke, you would have to store it.

- Ram


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 03, 2007 11:36 am 
Regular
Regular

Joined: Fri Oct 05, 2007 1:17 pm
Posts: 78
After studying my field mappings and bridges and a whole host of other elaborate Hibernate Search topics, I came to discover that it was indeed something silly. Very silly.

See if you can catch the error from excerpts from my previous messages:

Code:
On the Search tab in Luke, I apply the same query, and I get all the right hits. What is curious perhaps is that there are columns for _hibernate_class, keyWords.id, keyWords.name among others, but the keyWords.name column is empty while the keyWords.id column is populated with space-delimited IDs from the KEY_WORD table.



And this one:


Code:
But my tests with +keywords.name:Aluminum~0.4 return zip.


Can you see the problem?

If you can't, then I might feel a bit better. The issue is my spelling in the query. Where Luke was correctly using keyWords.name, I was using keywords.name with no capital W.

So yes, I am an idiot.

It just goes to show that even the simplest, most innocent things must not be overlooked.

A less obvious lesson learned here is that M:M searches are quite easy by declaring the recipient of the association the usual way and by annotating it on the owning class with @IndexedEmbedded.

Thanks to everyone for their help.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.