-->
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.  [ 8 posts ] 
Author Message
 Post subject: Query for a map-type field
PostPosted: Thu Apr 03, 2008 3:04 pm 
Beginner
Beginner

Joined: Wed Feb 27, 2008 12:34 pm
Posts: 21
Hi!

How can I access to a map-type field -for a given key- in a Hibernate Search query using MultiFieldQueryParser. I've tried this:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"field[key].value"},
new StandardAnalyzer());


but it doesn't works. I mean, there is no error, neither in compile time nor in runtime, but the query does not retrieve any result.

Thanks in advance!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 04, 2008 6:35 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

I am not quite sure what you are trying to do here. Maybe you can elaborate on your problem? How does your annotated (indexed) entity look like? And what do you mean with map-type field?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 04, 2008 11:11 am 
Beginner
Beginner

Joined: Wed Feb 27, 2008 12:34 pm
Posts: 21
Hi!

Sorry but at the moment -I think I'll not can take it until monday- I don't have the code. But it is very similar -if not the same- to:

...
@Entity
@Indexed
public class Ficha {

@Id
@DocumentId
private Integer id;

@IndexedEmbeded
private Translation translatedDescription;
....

...
@Entity
@Indexed
public class Translation {

@Id
@DocumentId
private Integer id;

@IndexedEmbeded
Map <Language, TranslationValue> translationValues;
....
...
@Entity
@Indexed
public class TranslationValue {

@Id
@DocumentId
private Integer id;

@Field(index=Index.TOKENIZED, store=Store.NO)
String value;
....

@Entity
@Indexed
public class Language {

@Id
@DocumentId
private Integer isoName
....



I've a got a a MultifieldQueryParse for the entitiy Ficha with an Language object like this:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[] {"translatedDescription.translationValues['language'].value"},
new StandardAnalyzer());

It never returns results, but if I don't use the language key:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String [] {"translatedDescription.translationValues.value"},
new StandardAnalyzer());

I obtain results. But obviously, I just want to do searchs for a given language.

Thank you very much for your time!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 04, 2008 2:19 pm 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

now I understand what you mean and I must say that I am intrigued that you get something at all working. As far as I know there is no default bridge for indexing a Map. Have you actually used Luke to see what goes into the index? Check http://hibernate.org/440.html to see how to use Luke to look into the Lucene index.

To index a Map I recommend you implement a custom FieldBridge (http://www.hibernate.org/hib_docs/search/reference/en/html_single/#d0e1624). How exactly you store the different key value pairs into the document depends on you and your usecase. I guess you could do something like translationValues.en, translationValukes.de, ... However, it is up to you to create these names. A syntax like translationValues['language'] won't work since a Lucene document is basically a simple key/value pair map where key and value are simple strings.

Last but not least - in case you want to do something language specific with your data (language specific stemming) you probably need to think about using a different Analyzer.

I hope this helps,

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 07, 2008 5:01 am 
Beginner
Beginner

Joined: Wed Feb 27, 2008 12:34 pm
Posts: 21
Hi! First of all, thank you very much for your time.

I've created this bridge:

public class MapLanguageBridge implements FieldBridge {

public void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost) {

final Map<Language, TranslationValue> map = (Map<Language, TranslationValue>) value;

for (final Map.Entry<Language, TranslationValue> entry : map.entrySet()) {

if (entry.getValue() == null)
continue;

final String propertyName = entry.getKey().getIsoName();
final String propertyValue = entry.getValue().getValue();

final Field field = new Field(propertyName, propertyValue, store, index);

if (boost != null)
field.setBoost(boost);

document.add(field);
}

}

}

My class Translation has these annotations:

@FieldBridge(impl = MapLanguageBridge.class)
@IndexedEmbedded
private Map< Language, TranslationValue > translationValues =
new HashMap< Language, TranslationValue >();

And I create the query like this:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"translatedDenominacion.translationValues." + idioma.getIsoName()}, new StandardAnalyzer());

But it does never returns results and I don't know the reason.


Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 07, 2008 7:06 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

don't use @IndexedEmbedded just annotate like this:

Code:
    @Field(index = Index.TOKENIZED, store = Store.YES)
    @FieldBridge(impl = MapLanguageBridge.class)
    private Map< Language, TranslationValue > translationValues =
        new HashMap< Language, TranslationValue >();


Looking at your bridge code you only use the language ISO code as field name, for this reason you should use

Code:
MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{idioma.getIsoName()}, new StandardAnalyzer());


But to make sure use Luke to open the created Lucene index and check the document field names. I am sure that once you see the actual document things will become much clearer.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 07, 2008 8:07 am 
Beginner
Beginner

Joined: Wed Feb 27, 2008 12:34 pm
Posts: 21
I've annotated the field as you said but the query does not return results.

Are you sure that the MultifieldQueryParser has to be like this?:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{idioma.getIsoName()}, new StandardAnalyzer());


I'm thinking in something like:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"translatedDescription" + idioma.getIsoName()}, new StandardAnalyzer());

I mean, the map field must be joined with the field translatedDescription.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 07, 2008 11:04 am 
Beginner
Beginner

Joined: Wed Feb 27, 2008 12:34 pm
Posts: 21
Hi!

Definitely you were right. I've tested the query with:

MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{idioma.getIsoName()}, new StandardAnalyzer());

and it works.


Thank you very much again!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.