Skip to content

Instantly share code, notes, and snippets.

@mp911de
Created November 12, 2013 07:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mp911de/7426942 to your computer and use it in GitHub Desktop.
Save mp911de/7426942 to your computer and use it in GitHub Desktop.
Leveraging dynamic queries
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:36
*/
public class FieldComparisonQLToken implements FieldQLToken {
private String field;
private String value;
private QueryComparator queryComparator = QueryComparator.EQUAL_TO;
public FieldComparisonQLToken(String field, String value) {
this.field = field;
this.value = value;
}
public FieldComparisonQLToken(String field, String value, QueryComparator queryComparator) {
this.field = field;
this.value = value;
this.queryComparator = queryComparator;
}
@Override
public String asQLString() {
switch (queryComparator) {
case NOT_EQUAL:
return "-" + field + ":" + value;
default:
return field + ":" + value;
}
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [field='").append(field).append('\'');
sb.append(", value='").append(value).append('\'');
sb.append(']');
return sb.toString();
}
}
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:36
*/
public class FieldNullComparisonQLToken implements FieldQLToken {
private String field;
private boolean mustBeNull;
public FieldNullComparisonQLToken(String field, boolean mustBeNull) {
this.mustBeNull = mustBeNull;
this.field = field;
}
@Override
public String asQLString() {
if (mustBeNull) {
return "-" + field + ":[* TO *]";
}
return field + ":[* TO *]";
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [field='").append(field).append('\'');
sb.append(", mustBeNull=").append(mustBeNull);
sb.append(']');
return sb.toString();
}
}
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:36
*/
public interface FieldQLToken extends SolrQLToken {
}
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:53
*/
public class NativeQLToken implements SolrQLToken {
private String ql;
public NativeQLToken(String ql) {
this.ql = ql;
}
@Override
public String asQLString() {
return ql;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [ql='").append(ql).append('\'');
sb.append(']');
return sb.toString();
}
}
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:37
*/
public enum OperatorToken
implements SolrQLToken {
AND,
OR;
@Override
public String asQLString() {
return name();
}
}
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:35
*/
public interface SolrQLToken
{
String asQLString();
}
import java.util.Stack;
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 07.11.13 12:43
*/
public class StackQLToken implements SolrQLToken {
private Stack<? extends SolrQLToken> stack;
public StackQLToken(Stack<? extends SolrQLToken> stack) {
this.stack = stack;
}
@Override
public String asQLString() {
StringBuilder builder = new StringBuilder();
SolrQLToken prevToken = null;
for (SolrQLToken qlToken : stack) {
if (prevToken != null) {
if (qlToken == prevToken || qlToken.getClass().equals(prevToken.getClass())) {
throw new IllegalStateException("Cannot create QL String because two same tokens follow each other: " + prevToken
+ " and " + qlToken + " (Query: " + this + ")");
}
}
if (builder.length() != 0) {
builder.append(' ');
}
if (qlToken instanceof StackQLToken) {
StackQLToken stack = (StackQLToken) qlToken;
if (!stack.stack.empty()) {
if (stack.stack.size() == 1) {
builder.append(qlToken.asQLString());
} else {
builder.append('(').append(qlToken.asQLString()).append(')');
}
}
} else {
builder.append(qlToken.asQLString());
}
prevToken = qlToken;
}
return builder.toString();
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [stack=").append(stack);
sb.append(']');
return sb.toString();
}
}
Stack<SolrQLToken> stack = new Stack<>();
for (Repository repo: query.getRepositories()) {
Stack<SolrQLToken> repoPredicateStack = new Stack<>();
repoPredicateStack.push(new FieldComparisonQLToken("ObjectStore", repo.getObjectStoreName()));
repoPredicateStack.push(OperatorToken.AND);
if (queryRepo.isIncludeSubClasses()) {
repoPredicateStack.push(new FieldComparisonQLToken("Path", repo.getDocumentClassName()));
} else {
repoPredicateStack.push(new FieldComparisonQLToken("Class", repo.getDocumentClassName()));
}
ClassDefinition classDefinition = classDefinitionProvider.get(repo.getObjectStoreName(), repo.getDocumentClassName());
Stack<SolrQLToken> nested = getSearchFieldsStatement(classDefinition, query.getFields());
if (!nested.isEmpty()) {
if (!repoPredicateStack.empty()) {
repoPredicateStack.push(OperatorToken.AND);
}
repoPredicateStack.addAll(nested);
}
if (!repoPredicateStack.empty()) {
if (!stack.empty()) {
stack.push(OperatorToken.OR);
}
stack.push(new StackQLToken(repoPredicateStack));
}
}
if(!stack.empty()) {
queries.add(new StackQLToken(stack).asQLString());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment