All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.redlink.solr.suggestion.result.SuggestionResultFactory Maven / Gradle / Ivy

package io.redlink.solr.suggestion.result;

import io.redlink.solr.suggestion.SuggestionRequestHandler;
import io.redlink.solr.suggestion.service.FieldAnalyzerService;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.SolrCore;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.util.DateMathParser;

public final class SuggestionResultFactory {

    public static final String RESULT_FIELD_COUNT = "count";

    private SuggestionResultFactory() {}

    /**
     * create a multi suggestion result
     *
     * @param core
     * @param rsp
     * @param fields
     * @param query
     * @param df
     * @param limit
     * @return a multi suggestion result
     */
    @SuppressWarnings({"java:S3776", "java:S107"})
    public static SuggestionResult createMultiValueResult(SolrCore core, SolrQueryResponse rsp, String[] fields, String query, String df, int termLimit, int limit, SuggestionRequestHandler.LimitType limitType) {
        SuggestionResultMulti result = new SuggestionResultMulti(limit, limitType);

        SimpleOrderedMap facets = (SimpleOrderedMap) ((SimpleOrderedMap) rsp.getValues().get("facet_counts")).get("facet_fields");

        //for each word
        String[] qps = query.split("([ +])");
        LinkedList> listOfFacetLists = new LinkedList<>();
        for (int i = 0; i < qps.length; i++) {
            LinkedList l = new LinkedList<>();
            listOfFacetLists.addLast(l);
            for (String field : fields) {
                Iterator iter = ((NamedList) facets.get(field)).iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = iter.next();
                    String s = " " + FieldAnalyzerService.analyzeString(core, df, entry.getKey());
                    //try if it maps to current fields
                    if (s.toLowerCase().contains(" " + qps[i].toLowerCase())) {
                        Integer count = entry.getValue();
                        if (count != null) {
                            l.addLast(new Facet(field, entry.getKey(), count));
                        }
                    }
                }
            }
        }

        if (listOfFacetLists.isEmpty()) {
            return result;
        }

        getMultiSuggestions(result, listOfFacetLists, 0, new ArrayList<>());

        return result;
    }

    /**
     * create multi suggestions recursively
     *
     * @param result
     * @param all
     * @param i
     * @param list
     */
    private static void getMultiSuggestions(SuggestionResultMulti result, List> all, int i, List list) {
        if (i < all.size()) {
            for (Facet facet : all.get(i)) {
                List fl = new ArrayList<>(list);
                if (!fl.contains(facet)) {
                    fl.add(facet);
                }
                getMultiSuggestions(result, all, ++i, fl);
            }
        } else {
            if (!list.isEmpty()) {
                SuggestionResultMulti.MultiFacet mf = result.createMultiFacet();
                for (Facet f : list) {
                    mf.add(f.getName(), f.getValue(), f.getCount());
                }
            }
        }
    }

    /**
     * create single suggestion result
     *
     * @param core
     * @param rsp
     * @param fields
     * @param q
     * @param df
     * @param limit
     * @return a single suggestion result
     */
    @SuppressWarnings({"java:S3776", "java:S107"})
    public static SuggestionResult createSingleValueResult(SolrCore core, SolrQueryResponse rsp, String[] fields, String q, String op, String df, int termLimit, int limit, SuggestionRequestHandler.LimitType limitType, SuggestionRequestHandler.Strategy strategy, String suggestionField, Map> intervals) {
        final SuggesionResultSingle result = new SuggesionResultSingle(limit, limitType);

        final SimpleOrderedMap facets = (SimpleOrderedMap) rsp.getValues().get("facets");

        //get results
        Pattern pattern = null;
        switch (strategy) {
            case exact:
                pattern = Pattern.compile("^" + Pattern.quote(q.trim()) + "\\S*|\\s" + Pattern.quote(q.trim()) + "\\S*");
                break;
            case permutate:
                final String[] split = q.trim().split("[ +]");
                StringBuilder w = new StringBuilder("^");

                final int maxLength = Math.min(split.length, termLimit);
                for (int i = 0; i < maxLength; i++) {
                    if (i > 0 && op.equals("OR")) {
                        w.append("|");
                    }
                    w.append("(?=.*\\b")
                            .append(Pattern.quote(split[i]))
                            .append("\\S*\\b)");
                }
                pattern = Pattern.compile(w.append(".+").toString(), Pattern.CASE_INSENSITIVE);
                break;
        }

        final Pattern word = pattern;
        if (intervals != null && !intervals.isEmpty()) {
            SuggesionResultInterval intervalResult = new SuggesionResultInterval(limit, limitType);
            for (String intervalName : intervals.keySet()) {
                final Date start = DateMathParser.parseMath(new Date(), (String) intervals.get(intervalName).get("start"));
                final LocalDateTime dateTimeStart = start.toInstant().atZone(ZoneId.of("UTC")).toLocalDateTime();

                final Date end = DateMathParser.parseMath(new Date(), (String) intervals.get(intervalName).get("end"));
                final LocalDateTime dateTimeEnd = end.toInstant().atZone(ZoneId.of("UTC")).toLocalDateTime();

                intervalResult.addInterval(intervalName, dateTimeStart, dateTimeEnd);
                final NamedList fieldFilters = (NamedList) facets.get(intervalName);
                for (String fieldName : fields) {
                    final String filterName = fieldName.concat("_filter");
                    if (fieldFilters.get(filterName) != null) {
                        final NamedList fieldResults = (NamedList) fieldFilters.get(filterName);
                        if ((Long) fieldResults.get(RESULT_FIELD_COUNT) > 0) {
                            List fieldValues = (List) (((NamedList) fieldResults.get(fieldName)).get("buckets"));
                            fieldValues.forEach(
                                    value -> {
                                        Matcher matcher = word.matcher(FieldAnalyzerService.analyzeString(core, df, value.get("val").toString()));
                                        if (matcher.find()) {
                                            intervalResult.addFacet(intervalName, fieldName, value.get("val").toString(), ((Long) value.get(RESULT_FIELD_COUNT)).intValue(), matcher.start());
                                        }
                                    }
                            );
                        }
                    }
                }
            }
            return intervalResult;
        } else {
            for (String fieldName : fields) {
                final String filterName = fieldName.concat("_filter");
                final NamedList fieldResults = (NamedList) facets.get(filterName);
                if ((Long) fieldResults.get(RESULT_FIELD_COUNT) > 0) {
                    final List fieldValues = (List) (((NamedList) fieldResults.get(fieldName)).get("buckets"));
                    fieldValues.forEach(
                            value -> {
                                final Matcher matcher = word.matcher(FieldAnalyzerService.analyzeString(core, df, value.get("val").toString()));
                                if (matcher.find()) {
                                    result.addFacet(fieldName, value.get("val").toString(), ((Long) value.get(RESULT_FIELD_COUNT)).intValue(), matcher.start());
                                }
                            }
                    );
                }
            }
        }

        return result;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy