Dheeraj Arora
Dheeraj Arora

Reputation: 608

Spring Data Solr - Multiple FilterQueries separated by OR

I'm trying to implement a filter search using spring data solr. I've following filters types and all have a set of filters.

  1. A
    • aa in (1,2,3)
    • ab between (2016-08-02 TO 2016-08-10)
  2. B
    • ba in (2,3,4)
    • bb between (550 TO 1000)

The Solr query which I want to achieve using Spring data solr is:

q=*:*&fq=(type:A AND aa:(1,2,3) AND ab:[2016-08-02 TO 2016-08-10]) OR (type:B AND ba:(2,3,4) AND bb:[550 TO 1000])

I'm not sure how to group a number of clauses of a type of filter and then have an OR operator.

Thanks in advance.

Upvotes: 5

Views: 2353

Answers (1)

cheffe
cheffe

Reputation: 9500

The trick is to flag the second Criteria via setPartIsOr(true) with an OR-ish nature. This method returns void, so it cannot be chained.

First aCriteria and bCriteria are defined as described. Then bCriteria is flagged as OR-ish. Then both are added to a SimpleFilterQuery. That in turn can be added to the actual Query. That is left that out in the sample.

The DefaultQueryParser in the end is used only to generate a String that can be used in the assertion to check that the query is generated as desired.

import org.junit.jupiter.api.Test;
import org.springframework.data.solr.core.DefaultQueryParser;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.FilterQuery;
import org.springframework.data.solr.core.query.SimpleFilterQuery;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CriteriaTest {

  @Test
  public void generateQuery() {
    Criteria aCriteria = 
        new Criteria("type").is("A")
            .connect().and("aa").in(1,2,3)
            .connect().and("ab").between("2016-08-02", "2016-08-10");
    Criteria bCriteria = 
        new Criteria("type").is("B")
            .connect().and("ba").in(2,3,4)
            .connect().and("bb").between("550", "1000");

    bCriteria.setPartIsOr(true); // that is the magic

    FilterQuery filterQuery = new SimpleFilterQuery();
    filterQuery.addCriteria(aCriteria);
    filterQuery.addCriteria(bCriteria);

    // verify the generated query string
    DefaultQueryParser dqp = new DefaultQueryParser(null);
    String actualQuery = dqp.getQueryString(filterQuery, null);
    String expectedQuery = 
        "(type:A AND aa:(1 2 3) AND ab:[2016\\-08\\-02 TO 2016\\-08\\-10]) OR " 
        + "((type:B AND ba:(2 3 4) AND bb:[550 TO 1000]))";
    System.out.println(actualQuery);
    assertEquals(expectedQuery, actualQuery);
  }
}

Upvotes: 5

Related Questions