3

Can't find full tutorial for spring-data-solr.

Have a question about migrating to spring-data-solr.

For example I have the following query on solarj:

SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.setParam("df", region);
query.setParam("fq", addType(param));
query.setParam("fl", region);
query.setRows(10000);
query.addSort(region, SolrQuery.ORDER.asc);

query.set(GroupParams.GROUP, true);
query.set(GroupParams.GROUP_FIELD, groupField);
query.set(GroupParams.GROUP_MAIN, true);
query.set(GroupParams.GROUP_FORMAT, "simple");
SolrTemplate server = /*initialization*/
server.execute(client -> client.query(SOLR_COLLECTION_NAME, query));

So how can I migrate this code to spring-data-solr Query class? Or even to SolrRepository if possible? You might wanna ask me what I have tried so far: now I tried to create solar query as:

Query query = new SimpleQuery("*:*");
query.setRows(10000);
query.addSort(new Sort(Direction.ASC, SCHOOL_REGION));

But how can I set params like "df", "fl", etc. and all of the group params? I don't see setters for it.

And the second question is can I use SolrCrudRepository for complicated query like this?

pvrforpranavvr
  • 2,708
  • 2
  • 24
  • 34
Tyulpan Tyulpan
  • 724
  • 1
  • 7
  • 17
  • This is from 3 years ago - I'm assuming you don't still need help. Looks like these days (and maybe 3 years ago) the Spring - Solr setup would have you create query methods using bean type naming conventions. https://docs.spring.io/spring-data/solr/docs/4.0.10.RELEASE/reference/html/#solr.query-methods.criterions The Product entity is returned, so my guess is that the fields in the entity would end up being automatically used in the `fl` values so the entities could be populated. List findByNameAndPopularity(String name, Integer popularity); – LeeWallen Aug 25 '19 at 17:13
  • @LeeWallen what about df? – Tyulpan Tyulpan Aug 27 '19 at 07:36

1 Answers1

2

This answer may help somebody, so:

spring-data-solr (v4.0.10.RELEASE) does not support DisMax Parameters, so you're not able to use these params by default, the solution was to create custom SolrQuery:

@Data
@EqualsAndHashCode(callSuper = true)
public class ExtendedQuery extends SimpleQuery {
    private List<String> queryFields;
    private String defaultField;
}

Then we can set these params like:

query.setDefaultField(SCHOOL_CITY);
query.setQueryFields(Arrays.asList("school_name^150.0", "school_city^30.0"));

One more thing you'll need is to create custom QueryParser:

public class ExtendedQueryParser extends QueryParserBase<AbstractQueryDecorator> {

    private final DefaultQueryParser defaultQueryParser;

    public ExtendedQueryParser(MappingContext mappingContext) {
        super(mappingContext);
        defaultQueryParser = new DefaultQueryParser(mappingContext);
    }

    @Override
    public final SolrQuery doConstructSolrQuery(
            AbstractQueryDecorator query, Class<?> domainType) {
        ExtendedQuery decoratedQuery = (ExtendedQuery) query.getDecoratedQuery();

        SolrQuery solrQuery = 
            defaultQueryParser.constructSolrQuery(decoratedQuery, domainType);

        Optional.ofNullable(decoratedQuery.getDefaultField())
            .ifPresent(defaultField -> 
                solrQuery.setParam(CommonParams.DF, defaultField));
        if (!CollectionUtils.isEmpty(decoratedQuery.getQueryFields())) {
            solrQuery.setParam(DisMaxParams.QF, 
                String.join(SPACE, decoratedQuery.getQueryFields()));
        }

        return solrQuery;
    }
}

The last step is to register this parser:

@Bean
public ExtendedQueryParser extendedQueryParser(SolrTemplate solrTemplate) {
    ExtendedQueryParser extendedQueryParser = new ExtendedQueryParser(null);
    solrTemplate.registerQueryParser(ExtendedQuery.class, extendedQueryParser);
    return extendedQueryParser;
}
Tyulpan Tyulpan
  • 724
  • 1
  • 7
  • 17