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

io.github.meilisearch.client.querybuilder.search.DefaultSearchRequest Maven / Gradle / Ivy

package io.github.meilisearch.client.querybuilder.search;

import io.github.meilisearch.client.querybuilder.MatchingStrategy;
import io.github.meilisearch.client.querybuilder.SortOrder;
import lombok.Value;

import java.util.*;

import static java.util.Optional.ofNullable;
import static io.github.meilisearch.client.querybuilder.DefaultQueryBuilder.SEARCH_PHRASE_DELIM;

public class DefaultSearchRequest extends BaseGet implements SearchRequest, SearchRequest.AroundPoint {

    public static final String STAR_WILDCARD = "*";
    private String query;
    private int offset = 0;
    private int limit = 20;
    private final List filters;

    private final List facets;

    private Set attributesToRetrieve;
    private Set attributesToCrop;

    private Integer cropLength;

    private String cropMarker = "…";

    private Set attributesToHighlight;

    private String highlightPreTag = "";

    private String highlightPostTag = "";

    private boolean showMatchesPosition;

    private final List sort;

    private MatchingStrategy matchingStrategy;

    private GeoPoint aroundPoint;

    public DefaultSearchRequest(String index) {
        super("/indexes/" + index + "/search");
        filters = new ArrayList<>();
        facets = new ArrayList<>();
        sort = new ArrayList<>();
    }

    @Override
    public SearchRequest fetchOnly(List fields) {
        return retrieveAttributes(fields);
    }

    @Override
    public SearchRequest startingAt(int offset) {
        this.offset = offset;
        return this;
    }

    @Override
    public SearchRequest fetch(int limit) {
        this.limit = limit;
        return this;
    }

    @Override
    public int limit() {
        return limit;
    }

    @Override
    public int offset() {
        return offset;
    }

    @Override
    public SearchRequest q(String q) {
        this.query = q;
        return this;
    }

    @Override
    public SearchRequest phrase(String phrase) {
        this.query = surroundPhrase(phrase);
        return this;
    }

    @Override
    public SearchRequest filter(String filter) {
        Objects.requireNonNull(filter);
        if(!filter.isEmpty()) {
            this.filters.add(filter);
        }
        return this;
    }

    @Override
    public SearchRequest appendFilters(Collection filters) {
        Objects.requireNonNull(filters);
        this.filters.addAll(filters);
        return this;
    }

    @Override
    public SearchRequest appendToQuery(String q) {
        this.query = Optional.ofNullable(this.query)
                .map(existingQuery -> existingQuery + " " + q)
                .orElse(q);
        return this;
    }

    @Override
    public SearchRequest appendPhraseToQuery(String q) {
        String phraseQ = surroundPhrase(q);
        this.query = Optional.ofNullable(this.query)
                .map(existingQuery -> existingQuery + " " + phraseQ)
                .orElse(phraseQ);
        return this;
    }

    @Override
    public SearchRequest clearFilters() {
        this.filters.clear();
        return this;
    }

    @Override
    public SearchRequest facet(String facet) {
        Objects.requireNonNull(facet);
        facets.add(facet);
        return this;
    }

    @Override
    public SearchRequest facets(Collection facets) {
        Objects.requireNonNull(facets);
        this.facets.addAll(facets);
        return this;
    }

    @Override
    public SearchRequest retrieveAttributes(Collection attributesToRetrieve) {
        Collection attrsOrElseStar = ofNullable(attributesToRetrieve)
                .filter(c -> !c.isEmpty())
                .orElseGet(Collections::emptyList);
        this.attributesToRetrieve = new HashSet<>(attrsOrElseStar);
        return this;
    }

    @Override
    public SearchRequest cropAllRetrievedAttributes() {
        this.attributesToCrop = Collections.singleton(STAR_WILDCARD);
        return this;
    }

    @Override
    public SearchRequest cropAttributes(Collection attributesToCrop) {
        Collection attrs = ofNullable(attributesToCrop).orElseGet(Collections::emptyList);
        this.attributesToCrop = new HashSet<>(attrs);
        return this;
    }

    @Override
    public SearchRequest cropLength(int cropLength) {
        if(cropLength > 0) {
            this.cropLength = cropLength;
        }
        return this;
    }

    @Override
    public SearchRequest markCropBoundariesWith(String cropMarker) {
        this.cropMarker = cropMarker;
        return this;
    }

    @Override
    public SearchRequest highlightAllRetrievedAttributes() {
        this.attributesToHighlight = Collections.singleton(STAR_WILDCARD);
        return this;
    }

    @Override
    public SearchRequest highlightAttributes(Collection attributesToHighlight) {
        Collection attrs = ofNullable(attributesToHighlight).orElseGet(Collections::emptyList);
        this.attributesToHighlight = new HashSet<>(attrs);
        return this;
    }

    @Override
    public SearchRequest highlightTags(String preTag, String postTag) {
        if(preTag != null && postTag != null && !preTag.isBlank() && !postTag.isBlank()) {
            this.highlightPreTag = preTag;
            this.highlightPostTag = postTag;
        }
        return this;
    }

    @Override
    public SearchRequest showMatchesPosition(boolean showMatchesPosition) {
        this.showMatchesPosition = showMatchesPosition;
        return this;
    }


    @Override
    public SearchRequest sortBy(String field, SortOrder sortOrder) {
        Objects.requireNonNull(field);
        this.sort.add(field + ":" + sortOrder.toString());
        return this;
    }

    @Override
    public SearchRequest sortAscBy(String field) {
        return sortBy(field, SortOrder.ASC);
    }

    @Override
    public SearchRequest sortDescBy(String field) {
        return sortBy(field, SortOrder.DESC);
    }

    @Override
    public SearchRequest sortByDistanceFromPoint(double lat, double lon, SortOrder sortOrder) {
        String geoPoint = "_geoPoint(" + lat + ", " + lon + ")";
        return sortBy(geoPoint, sortOrder);
    }


    @Override
    public SearchRequest matchDocumentsContainingAllQueryTerms() {
        return matchingStrategy(MatchingStrategy.ALL);
    }

    @Override
    public SearchRequest matchingStrategy(MatchingStrategy matchingStrategy) {
        this.matchingStrategy = matchingStrategy;
        return this;
    }

    @Override
    public AroundPoint aroundPoint(double lat, double lon) {
        this.aroundPoint = new GeoPoint(lat, lon);
        return this;
    }

    @Override
    public String json(JsonWriter jsonWriter) {
        Map body = new HashMap<>();
        ofNullable(query)
                .filter(s -> !s.isBlank())
                .ifPresent(s -> body.put("q", s));

        Optional.of(this.filters)
                .filter(l -> !l.isEmpty())
                .ifPresent(l -> body.put("filter", l));

        Optional.of(this.facets)
                .filter(l -> !l.isEmpty())
                .ifPresent(l -> body.put("facets", l));

        Optional.ofNullable(this.attributesToRetrieve)
                .filter(l -> !l.isEmpty())
                .ifPresent(l -> body.put("attributesToRetrieve", l));

        Optional.ofNullable(this.attributesToCrop)
                .filter(l -> !l.isEmpty())
                .ifPresent(l -> {
                    body.put("attributesToCrop", l);
                    body.put("cropMarker", cropMarker);
                });
        ofNullable(cropLength)
                .ifPresent(length -> body.put("cropLength", length));

        Optional.ofNullable(this.attributesToHighlight)
                .filter(l -> !l.isEmpty())
                .ifPresent(l -> {
                    body.put("attributesToHighlight", l);
                    body.put("highlightPreTag", this.highlightPreTag);
                    body.put("highlightPostTag", this.highlightPostTag);
                });

        if(showMatchesPosition) {
            body.put("showMatchesPosition", true);
        }

        Optional.of(this.sort)
                .filter(l -> !l.isEmpty())
                .ifPresent(l -> body.put("sort", l));

        Optional.of(offset)
                .filter(off -> off > 0)
                .ifPresent(off -> body.put("offset", offset()));

        Optional.of(limit)
                .filter(lim -> lim != 20)
                .ifPresent(lim -> body.put("limit", limit()));

        ofNullable(matchingStrategy)
                .ifPresent(strategy -> body.put("matchingStrategy", strategy.toString()));

        return jsonWriter.json(body);
    }

    @Override
    public SearchRequest withinDistanceInMeters(int distanceInMeters) {
        String geoFilter = "_geoRadius(" + aroundPoint.getLat() + ", " + aroundPoint.getLon() + ", " + distanceInMeters + ")";
        return this.filter(geoFilter);
    }

    @Value
    static class GeoPoint {
        double lat;
        double lon;
    }

    private static String surroundPhrase(String phrase) {
        String surroundedPhrase;
        if (!phrase.startsWith(SEARCH_PHRASE_DELIM)) {
            surroundedPhrase = SEARCH_PHRASE_DELIM + phrase + SEARCH_PHRASE_DELIM;
        } else {
            surroundedPhrase = phrase;
        }
        return surroundedPhrase;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy