Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include QueryBuilder implementations #3107

Merged
merged 4 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package redis.clients.jedis.search.querybuilder;

/**
* A disjunct node. evaluates to true if any of its children are false. Conversely, this node
* evaluates to false only iff <b>all</b> of its children are true, making it the exact inverse of
* {@link IntersectNode}
*
* In RS, it looks like:
*
* {@code -(@f1:v1 @f2:v2)}
*
* @see DisjunctUnionNode which evalutes to true if <b>all</b> its children are false.
*/
public class DisjunctNode extends IntersectNode {
@Override
public String toString(Parenthesize mode) {
String ret = super.toString(Parenthesize.NEVER);
if (shouldParenthesize(mode)) {
return "-(" + ret + ")";
} else {
return "-" + ret;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package redis.clients.jedis.search.querybuilder;

/**
* A disjunct union node is the inverse of a {@link UnionNode}. It evaluates to true only iff
* <b>all</b> its children are false. Conversely, it evaluates to false if <b>any</b> of its
* children are true.
*
* As an RS query it looks like {@code -(@f1:v1|@f2:v2)}
*
* @see DisjunctNode which evaluates to true if <b>any</b> of its children are false.
*/
public class DisjunctUnionNode extends DisjunctNode {
@Override
protected String getJoinString() {
return "|";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package redis.clients.jedis.search.querybuilder;

/**
* @author mnunberg on 2/23/18.
*/
public class DoubleRangeValue extends RangeValue {

private final double from;
private final double to;

private static void appendNum(StringBuilder sb, double n, boolean inclusive) {
if (!inclusive) {
sb.append("(");
}
if (n == Double.NEGATIVE_INFINITY) {
sb.append("-inf");
} else if (n == Double.POSITIVE_INFINITY) {
sb.append("inf");
} else {
sb.append(n);
}
}

public DoubleRangeValue(double from, double to) {
this.from = from;
this.to = to;
}

@Override
protected void appendFrom(StringBuilder sb, boolean inclusive) {
appendNum(sb, from, inclusive);
}

@Override
protected void appendTo(StringBuilder sb, boolean inclusive) {
appendNum(sb, to, inclusive);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package redis.clients.jedis.search.querybuilder;

import java.util.Locale;
import redis.clients.jedis.args.GeoUnit;

/**
* Created by mnunberg on 2/23/18.
*/
public class GeoValue extends Value {

private final GeoUnit unit;
private final double lon;
private final double lat;
private final double radius;

public GeoValue(double lon, double lat, double radius, GeoUnit unit) {
this.lon = lon;
this.lat = lat;
this.radius = radius;
this.unit = unit;
}

@Override
public String toString() {
return "[" + lon + " " + lat + " " + radius
+ " " + unit.name().toLowerCase(Locale.ENGLISH) + "]";
}

@Override
public boolean isCombinable() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package redis.clients.jedis.search.querybuilder;

/**
* The intersection node evaluates to true if any of its children are true.
*
* In RS: {@code @f1:v1 @f2:v2}
*/
public class IntersectNode extends QueryNode {
@Override
protected String getJoinString() {
return " ";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package redis.clients.jedis.search.querybuilder;

public class LongRangeValue extends RangeValue {

private final long from;
private final long to;

@Override
public boolean isCombinable() {
return false;
}

private static void appendNum(StringBuilder sb, long n, boolean inclusive) {
if (!inclusive) {
sb.append("(");
}
if (n == Long.MIN_VALUE) {
sb.append("-inf");
} else if (n == Long.MAX_VALUE) {
sb.append("inf");
} else {
sb.append(Long.toString(n));
}
}

public LongRangeValue(long from, long to) {
this.from = from;
this.to = to;
}

@Override
protected void appendFrom(StringBuilder sb, boolean inclusive) {
appendNum(sb, from, inclusive);
}

@Override
protected void appendTo(StringBuilder sb, boolean inclusive) {
appendNum(sb, to, inclusive);
}
}
50 changes: 50 additions & 0 deletions src/main/java/redis/clients/jedis/search/querybuilder/Node.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package redis.clients.jedis.search.querybuilder;

import redis.clients.jedis.search.Query;

/**
* Created by mnunberg on 2/23/18.
*
* Base node interface
*/
public interface Node {

enum Parenthesize {

/**
* Always encapsulate
*/
ALWAYS,

/**
* Never encapsulate. Note that this may be ignored if parentheses are semantically required
* (e.g. {@code @foo:(val1|val2)}. However something like {@code @foo:v1 @bar:v2} need not be
* parenthesized.
*/

NEVER,
/**
* Determine encapsulation based on number of children. If the node only has one child, it is
* not parenthesized, if it has more than one child, it is parenthesized
*/

DEFAULT
}

/**
* Returns the string form of this node.
*
* @param mode Whether the string should be encapsulated in parentheses {@code (...)}
* @return The string query.
*/
String toString(Parenthesize mode);

/**
* Returns the string form of this node. This may be passed to
* {@link redis.clients.jedis.UnifiedJedis#ftSearch(String, Query)}
*
* @return The query string.
*/
@Override
String toString();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package redis.clients.jedis.search.querybuilder;

/**
* Created by mnunberg on 2/23/18.
*
* The optional node affects scoring and ordering. If it evaluates to true, the result is ranked
* higher. It is helpful to combine it with a {@link UnionNode} to rank a document higher if it
* meets one of several criteria.
*
* In RS: {@code ~(@lang:en @country:us)}.
*/
public class OptionalNode extends IntersectNode {

@Override
public String toString(Parenthesize mode) {
String ret = super.toString(Parenthesize.NEVER);
if (shouldParenthesize(mode)) {
return "~(" + ret + ")";
}
return "~" + ret;
}
}
Loading