Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Need help indexing a map property queried by map key
PostPosted: Tue Apr 03, 2012 11:53 am 
Newbie

Joined: Thu Dec 14, 2006 6:42 am
Posts: 14
In my domain model a "Product" object has a "Map<String, ProductDescription> descriptions" property which stores localized product descriptions.
The key of the map is the iso3 language code.
The value of the map is an instance of ProductDescription which holds a "localeCode" String field (same as the iso3 map key above) and a "value" String field.
So for example myProduct.getDescriptions().get("eng").getValue() returns the english description of the product.

I need to be able to query product descriptions in the language of the user.

My first attempt used @IndexedEmbedded on the "descriptions" field of Product, and @Field on the "localeCode" and "value" fields of ProductDescription.
This worked almost fine, because I could query for a product by using the "descriptions.localeCode" and "descriptions.value" fields.
The problem was that I couldn't query for a specific localeCode-value couple, so I ended up with Products matching a description in the wrong language.

My last attempt is using a FieldBridge to convert the "descriptions" field to a fileld that contains the localeCode in the name, so I get the fields "descriptions.eng", "descriptions.ita" etc.
Everything looks fine through Luke, but when I query for "descriptions.eng" I get a SearchException: "Unable to find field descriptions.eng in com.my.entity.Product".

I'm using Hibernate Search 3.4.2.Final on Hibernate Core 3.6.0 and Lucene Core 3.1.0

Is there a way to achieve my goal?

Some simplified code snippets
Code:
@Indexed
@Entity
public class Product {
...
   @Field
   @FieldBridge(impl = ProductDescriptionMapBridge.class)
   @OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
   @JoinColumn(name="Product_id")
   @MapKey(name="localeCode")
   protected Map<String, ProductDescription> getDescriptions() {
      return descriptions;
   }
}

@Entity
public class ProductDescription {
...
   public String getLocaleCode() {
      return localeCode; // iso3 language code
   }

   public String getValue() {
      return value; // localized description
   }
}

public class ProductDescriptionMapBridge implements FieldBridge {
   public void set(String fieldName, Object fieldValue, Document document, LuceneOptions luceneOptions) {
         Map<String, ProductDescription> productDescriptionMap = (Map<String, ProductDescription>) fieldValue;
         for (String localeCode : productDescriptionMap.keySet()) {
            luceneOptions.addFieldToDocument(
                  fieldName + "." + localeCode,
                  productDescriptionMap.get(localeCode).getValue(),
                  document);
         }
   }
}

The query:

Code:
         Transaction tx = fullTextSession.beginTransaction();
         QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Product.class).get();
         org.apache.lucene.search.Query query = queryBuilder.keyword()
               .onFields("descriptions.eng")
               .matching("quick brown fox")
               .createQuery();
         org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(query, Product.class);
         result = hibQuery.list();         
         tx.commit();

The exception:

Code:
org.hibernate.search.SearchException: Unable to find field descriptions.eng in com.my.entity.Product
   at org.hibernate.search.engine.DocumentBuilderIndexedEntity.objectToString(DocumentBuilderIndexedEntity.java:688) ~[hibernate-search-3.4.2.Final.jar:3.4.2.Final]
   at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.buildSearchTerm(ConnectedMultiFieldsTermQueryBuilder.java:138) ~[hibernate-search-3.4.2.Final.jar:3.4.2.Final]
   at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.createQuery(ConnectedMultiFieldsTermQueryBuilder.java:92) ~[hibernate-search-3.4.2.Final.jar:3.4.2.Final]
   at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.createQuery(ConnectedMultiFieldsTermQueryBuilder.java:73) ~[hibernate-search-3.4.2.Final.jar:3.4.2.Final]
   at com.my.cms.action.admin.SearchAction.test(SearchAction.java:61) ~[SearchAction.class:na]
   

Thank you.


Top
 Profile  
 
 Post subject: Re: Need help indexing a map property queried by map key
PostPosted: Thu Apr 05, 2012 5:33 am 
Newbie

Joined: Thu Dec 14, 2006 6:42 am
Posts: 14
A luky search pointed me to this post that seems to solve the problem:

https://forum.hibernate.org/viewtopic.php?f=9&t=1008943

If I use

.onFields("descriptions.eng").ignoreFieldBridge()

in the query, the exception disappears and all is (almost) fine.

The problem I have now is that the index is not updated when the description value is modified, and using "@ContainedIn" as for embedded indexes doesn't do the trick... but I guess I'll open another topic for that.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 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.