Filter out document by ID


#1

What’s the recommended approach to filter out a specific document by ID from search results?

Long id = ...;
String idValue = String.valueOf(id);

Option 1

...
.must(queryBuilder
  .range()
  .onField("id")
  .from(idValue)
  .to(idValue)
  .createQuery())
.not()
...

Option 2

...
.must(queryBuilder
  .phrase()
  .onField("id")
  .sentence(idValue)
  .createQuery())
.not()
...

Option 3

Any other.


#2

In Hibernate Search 5, you should do this. In Search 6 and above we hope to provide a better alternative.

Long idToExclude = ...;
// Do not convert the ID yourself, Hibernate Search will do it.
...
.must(queryBuilder
  .keyword()
  .onField("id") // Use the actual name of your ID field here, e.g if it's "identifier", use "identifier"
  /*
   * Ignoring the analyzer is not needed in 5.10 and above,
   * but may be needed in 5.9 and below, depending on the exact version.
   * When in doubt, the safest option for ID matching is to ignore analyzers explicitly.
   * See https://hibernate.atlassian.net/browse/HSEARCH-3039
   */
  .ignoreAnalyer()
  .matching(idToExclude)
  .createQuery())
.not()
...

If you need to exclude multiple IDs, use multiple “must not” clauses.

Or if you really need to ignore a range of IDs:

Long minIdToExclude = ...;
Long maxIdToExclude = ...;
// Do not convert the IDs yourself, Hibernate Search will do it.
...
.must(queryBuilder
  .range()
  .onField("id")
  /*
   * Ignoring the analyzer is not needed in 5.10 and above,
   * but may be needed in 5.9 and below, depending on the exact version.
   * When in doubt, the safest option for ID matching is to ignore analyzers explicitly.
   * See https://hibernate.atlassian.net/browse/HSEARCH-3039
   */
  .ignoreAnalyer()
  .from(minIdToExclude).to(maxIdToExclude)
  .createQuery())
.not()
...

If you’re after more “generic” solutions, and not a solution to apply to just one query, then you might be interested in full-text filters. It’s just syntactic sugar, though.


#3

That seems the best approach, thanks.