
io.redisearch.Query Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jredisearch Show documentation
Show all versions of jredisearch Show documentation
Official client for Redis Search
package io.redisearch;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.util.SafeEncoder;
/**
* Query represents query parameters and filters to load results from the engine
*/
public class Query {
/**
* Filter represents a filtering rules in a query
*/
private abstract static class Filter {
public final String property;
public abstract void serializeRedisArgs(List args);
public Filter(String property) {
this.property = property;
}
}
/**
* NumericFilter wraps a range filter on a numeric field. It can be inclusive or exclusive
*/
public static class NumericFilter extends Filter {
private final double min;
private final boolean exclusiveMin;
private final double max;
private final boolean exclusiveMax;
public NumericFilter(String property, double min, boolean exclusiveMin, double max, boolean exclusiveMax) {
super(property);
this.min = min;
this.max = max;
this.exclusiveMax = exclusiveMax;
this.exclusiveMin = exclusiveMin;
}
public NumericFilter(String property, double min, double max) {
this(property, min, false, max, false);
}
private byte[] formatNum(double num, boolean exclude) {
if (num == Double.POSITIVE_INFINITY) {
return Keywords.POSITIVE_INFINITY.getRaw();
}
if (num == Double.NEGATIVE_INFINITY) {
return Keywords.NEGATIVE_INFINITY.getRaw();
}
return exclude ? SafeEncoder.encode("(" + num) : Protocol.toByteArray(num);
}
@Override
public void serializeRedisArgs(List args) {
args.add(Keywords.FILTER.getRaw());
args.add(SafeEncoder.encode(property));
args.add(formatNum(min, exclusiveMin));
args.add(formatNum(max, exclusiveMax));
}
}
/**
* GeoFilter encapsulates a radius filter on a geographical indexed fields
*/
public static class GeoFilter extends Filter {
public static final String KILOMETERS = "km";
public static final String METERS = "m";
public static final String FEET = "ft";
public static final String MILES = "mi";
private final double lon;
private final double lat;
private final double radius;
private final String unit;
public GeoFilter(String property, double lon, double lat, double radius, String unit) {
super(property);
this.lon = lon;
this.lat = lat;
this.radius = radius;
this.unit = unit;
}
@Override
public void serializeRedisArgs(List args) {
args.add(Keywords.GEOFILTER.getRaw());
args.add(SafeEncoder.encode(property));
args.add(Protocol.toByteArray(lon));
args.add(Protocol.toByteArray(lat));
args.add(Protocol.toByteArray(radius));
args.add(SafeEncoder.encode(unit));
}
}
public static class Paging {
int offset;
int num;
public Paging(int offset, int num) {
this.offset = offset;
this.num = num;
}
}
public static class HighlightTags {
private final String open;
private final String close;
public HighlightTags(String open, String close) {
this.open = open;
this.close = close;
}
}
/**
* The query's filter list. We only support AND operation on all those filters
*/
protected final List _filters = new LinkedList<>();
/**
* The textual part of the query
*/
protected final String _queryString;
/**
* The sorting parameters
*/
protected final Paging _paging = new Paging(0, 10);
protected boolean _verbatim = false;
protected boolean _noContent = false;
protected boolean _noStopwords = false;
protected boolean _withScores = false;
protected boolean _withPayloads = false;
protected String _language = null;
protected String[] _fields = null;
protected String[] _keys = null;
protected String[] _returnFields = null;
protected String[] highlightFields = null;
protected String[] summarizeFields = null;
protected String[] highlightTags = null;
protected String summarizeSeparator = null;
protected int summarizeNumFragments = -1;
protected int summarizeFragmentLen = -1;
protected byte []_payload = null;
protected String _sortBy = null;
protected boolean _sortAsc = true;
protected boolean wantsHighlight = false;
protected boolean wantsSummarize = false;
/**
* Create a new index
*
* @param queryString the textual part of the query
*/
public Query(String queryString) {
_queryString = queryString;
}
public void serializeRedisArgs(List args) {
args.add(SafeEncoder.encode(_queryString));
if (_verbatim) {
args.add(Keywords.VERBATIM.getRaw());
}
if (_noContent) {
args.add(Keywords.NOCONTENT.getRaw());
}
if (_noStopwords) {
args.add(Keywords.NOSTOPWORDS.getRaw());
}
if (_withScores) {
args.add(Keywords.WITHSCORES.getRaw());
}
if (_withPayloads) {
args.add(Keywords.WITHPAYLOADS.getRaw());
}
if (_language != null) {
args.add(Keywords.LANGUAGE.getRaw());
args.add(SafeEncoder.encode(_language));
}
if (_fields != null && _fields.length > 0) {
args.add(Keywords.INFIELDS.getRaw());
args.add(Protocol.toByteArray(_fields.length));
for (String f : _fields) {
args.add(SafeEncoder.encode(f));
}
}
if (_sortBy != null) {
args.add(Keywords.SORTBY.getRaw());
args.add(SafeEncoder.encode(_sortBy));
args.add((_sortAsc ? Keywords.ASC : Keywords.DESC).getRaw());
}
if (_payload != null) {
args.add(Keywords.PAYLOAD.getRaw());
args.add(_payload);
}
if (_paging.offset != 0 || _paging.num != 10) {
args.addAll(Arrays.asList(Keywords.LIMIT.getRaw(),
Protocol.toByteArray(_paging.offset),
Protocol.toByteArray(_paging.num)
));
}
if (!_filters.isEmpty()) {
for (Filter f : _filters) {
f.serializeRedisArgs(args);
}
}
if (wantsHighlight) {
args.add(Keywords.HIGHLIGHT.getRaw());
if (highlightFields != null) {
args.add(Keywords.FIELDS.getRaw());
args.add(Protocol.toByteArray(highlightFields.length));
for (String s : highlightFields) {
args.add(SafeEncoder.encode(s));
}
}
if (highlightTags != null) {
args.add(Keywords.TAGS.getRaw());
for (String t : highlightTags) {
args.add(SafeEncoder.encode(t));
}
}
}
if (wantsSummarize) {
args.add(Keywords.SUMMARIZE.getRaw());
if (summarizeFields != null) {
args.add(Keywords.FIELDS.getRaw());
args.add(Protocol.toByteArray(summarizeFields.length));
for (String s: summarizeFields) {
args.add(SafeEncoder.encode(s));
}
}
if (summarizeNumFragments != -1) {
args.add(Keywords.FRAGS.getRaw());
args.add(Protocol.toByteArray(summarizeNumFragments));
}
if (summarizeFragmentLen != -1) {
args.add(Keywords.LEN.getRaw());
args.add(Protocol.toByteArray(summarizeFragmentLen));
}
if (summarizeSeparator != null) {
args.add(Keywords.SEPARATOR.getRaw());
args.add(SafeEncoder.encode(summarizeSeparator));
}
}
if (_keys != null && _keys.length > 0) {
args.add(Keywords.INKEYS.getRaw());
args.add(Protocol.toByteArray(_keys.length));
for (String f : _keys) {
args.add(SafeEncoder.encode(f));
}
}
if (_returnFields != null && _returnFields.length > 0) {
args.add(Keywords.RETURN.getRaw());
args.add(Protocol.toByteArray( _returnFields.length));
for (String f : _returnFields) {
args.add(SafeEncoder.encode(f));
}
}
}
/**
* Limit the results to a certain offset and limit
*
* @param offset the first result to show, zero based indexing
* @param limit how many results we want to show
* @return the query itself, for builder-style syntax
*/
public Query limit(Integer offset, Integer limit) {
_paging.offset = offset;
_paging.num = limit;
return this;
}
/**
* Add a filter to the query's filter list
* @param f either a numeric or geo filter object
* @return the query itself
*/
public Query addFilter(Filter f) {
_filters.add(f);
return this;
}
/* Set the query payload to be evaluated by the scoring function */
public Query setPayload(byte []payload) {
_payload = payload;
return this;
}
/**
* Set the query to verbatim mode, disabling stemming and query expansion
* @return the query object
*/
public Query setVerbatim() {
this._verbatim = true;
return this;
}
public boolean getNoContent() {
return _noContent;
}
/**
* Set the query not to return the contents of documents, and rather just return the ids
* @return the query itself
*/
public Query setNoContent() {
this._noContent = true;
return this;
}
/**
* Set the query not to filter for stopwords. In general this should not be used
* @return the query object
*/
public Query setNoStopwords() {
this._noStopwords = true;
return this;
}
public boolean getWithScores() {
return _withScores;
}
/**
* Set the query to return a factored score for each results. This is useful to merge results from multiple queries.
* @return the query object itself
*/
public Query setWithScores() {
this._withScores = true;
return this;
}
public boolean getWithPayloads() {
return _withPayloads;
}
/**
* @deprecated {@link #setWithPayload()}
*/
@Deprecated
public Query setWithPaload() {
return this.setWithPayload();
}
/**
* Set the query to return object payloads, if any were given
*
* @return the query object itself
* */
public Query setWithPayload() {
this._withPayloads = true;
return this;
}
/**
* Set the query language, for stemming purposes
* @param language a language. see http://redisearch.io for documentation on languages and stemming
*
* @return the query object itself
*/
public Query setLanguage(String language) {
this._language = language;
return this;
}
/**
* Limit the query to results that are limited to a specific set of fields
* @param fields a list of TEXT fields in the schemas
* @return the query object itself
*/
public Query limitFields(String... fields) {
this._fields = fields;
return this;
}
/**
* Limit the query to results that are limited to a specific set of keys
* @param keys a list of TEXT fields in the schemas
* @return the query object itself
*/
public Query limitKeys(String... keys) {
this._keys = keys;
return this;
}
/**
* Result's projection - the fields to return by the query
* @param fields a list of TEXT fields in the schemas
* @return the query object itself
*/
public Query returnFields(String... fields) {
this._returnFields = fields;
return this;
}
public Query highlightFields(HighlightTags tags, String... fields) {
if (fields == null || fields.length > 0) {
highlightFields = fields;
}
if (tags != null) {
highlightTags = new String[]{tags.open, tags.close};
} else {
highlightTags = null;
}
wantsHighlight = true;
return this;
}
public Query highlightFields(String... fields) {
return highlightFields(null, fields);
}
public Query summarizeFields(int contextLen, int fragmentCount, String separator, String ... fields) {
if (fields == null || fields.length > 0) {
summarizeFields = fields;
}
summarizeFragmentLen = contextLen;
summarizeNumFragments = fragmentCount;
summarizeSeparator = separator;
wantsSummarize = true;
return this;
}
public Query summarizeFields(String... fields) {
return summarizeFields(-1, -1, null, fields);
}
/**
* Set the query to be sorted by a Sortable field defined in the schema
* @param field the sorting field's name
* @param ascending if set to true, the sorting order is ascending, else descending
* @return the query object itself
*/
public Query setSortBy(String field, boolean ascending) {
_sortBy = field;
_sortAsc = ascending;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy