gmansoor
gmansoor

Reputation: 509

Hibernate search / lucene search in multiple fields child collections

I am using Hibernate Search in my application. One of child collections is mapped as IndexedEmbedded. Child object have two fields, one id and other is date (using date resoultion to milliseconds). When I search for id=1 (or some value) and date equals to another, I get the results of all the cases where first and second match. I want to get only records where both fields are matched in the same child, but I get matches in different childs, resulting in much higher results. Here is the snippet of the code

Main class is User

@Indexed
public class User {...

@IndexedEmbedded(prefix = "score_")
public List<Score> getScores() {...}

Score class is @Indexed public class Score {...

@Id
@DocumentId
public Integer getId() {...}

@Field
public Integer value

@Field(analyze = Analyze.NO, indexNullAs="_null_")
@DateBridge(resolution = Resolution.MILLISECOND)
public Date getScoreTime()

In my search code, I am doing the following

QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(User.class).get();

BooleanQuery subQuery = new BooleanQuery();
subQuery.add(queryBuilder.keyword().onField("score_id").matching(20).createQuery(), BooleanClause.Occur.MUST);
subQuery.add(queryBuilder.keyword().onField("score_scoreTime").ignoreFieldBridge().matching("_null").createQuery(), BooleanClause.Occur.MUST);

Search on value field (instead of scoreTime) have the same behavior. If I search separately on any of the fields, I get correct result.

Any suggestions?

Upvotes: 3

Views: 1984

Answers (1)

Espresso
Espresso

Reputation: 5739

Have you tried this syntax:

//look for users whos id is 1 and createDate is more than lastMonth
Date lastMonth = ...;
QueryBuilder userQB = searchFactory.buildQueryBuilder().forEntity( User.class ).get();

Query luceneQuery = userQB
    .bool()
      .must( userQB.keyword().onField("id").matching("1").createQuery() )
      .must( userQB.range().onField("creationDate").above(lastMonth)
        .createQuery() )
    .createQuery();

Upvotes: 1

Related Questions