Search in sources :

Example 1 with TermsFilter

use of org.apache.lucene.queries.TermsFilter in project titan by thinkaurelius.

the class LuceneIndex method convertQuery.

private final SearchParams convertQuery(Condition<?> condition, KeyInformation.StoreRetriever informations) {
    SearchParams params = new SearchParams();
    if (condition instanceof PredicateCondition) {
        PredicateCondition<String, ?> atom = (PredicateCondition) condition;
        Object value = atom.getValue();
        String key = atom.getKey();
        TitanPredicate titanPredicate = atom.getPredicate();
        if (value instanceof Number) {
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
            Preconditions.checkArgument(value instanceof Number);
            params.addFilter(numericFilter(key, (Cmp) titanPredicate, (Number) value));
        } else if (value instanceof String) {
            Mapping map = Mapping.getMapping(informations.get(key));
            if ((map == Mapping.DEFAULT || map == Mapping.TEXT) && !titanPredicate.toString().startsWith("CONTAINS"))
                throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
            if (map == Mapping.STRING && titanPredicate.toString().startsWith("CONTAINS"))
                throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
            if (titanPredicate == Text.CONTAINS) {
                value = ((String) value).toLowerCase();
                BooleanFilter b = new BooleanFilter();
                for (String term : Text.tokenize((String) value)) {
                    b.add(new TermsFilter(new Term(key, term)), BooleanClause.Occur.MUST);
                }
                params.addFilter(b);
            } else if (titanPredicate == Text.CONTAINS_PREFIX) {
                value = ((String) value).toLowerCase();
                params.addFilter(new PrefixFilter(new Term(key, (String) value)));
            } else if (titanPredicate == Text.PREFIX) {
                params.addFilter(new PrefixFilter(new Term(key, (String) value)));
            } else if (titanPredicate == Text.REGEX) {
                RegexpQuery rq = new RegexpQuery(new Term(key, (String) value));
                params.addQuery(rq);
            } else if (titanPredicate == Text.CONTAINS_REGEX) {
                // This is terrible -- there is probably a better way
                RegexpQuery rq = new RegexpQuery(new Term(key, ".*" + (value) + ".*"));
                params.addQuery(rq);
            } else if (titanPredicate == Cmp.EQUAL) {
                params.addFilter(new TermsFilter(new Term(key, (String) value)));
            } else if (titanPredicate == Cmp.NOT_EQUAL) {
                BooleanFilter q = new BooleanFilter();
                q.add(new TermsFilter(new Term(key, (String) value)), BooleanClause.Occur.MUST_NOT);
                params.addFilter(q);
            } else
                throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
        } else if (value instanceof Geoshape) {
            Preconditions.checkArgument(titanPredicate == Geo.WITHIN, "Relation is not supported for geo value: " + titanPredicate);
            Shape shape = ((Geoshape) value).convert2Spatial4j();
            SpatialArgs args = new SpatialArgs(SpatialOperation.IsWithin, shape);
            params.addFilter(getSpatialStrategy(key).makeFilter(args));
        } else if (value instanceof Date) {
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
            params.addFilter(numericFilter(key, (Cmp) titanPredicate, ((Date) value).getTime()));
        } else if (value instanceof Instant) {
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on instant types: " + titanPredicate);
            params.addFilter(numericFilter(key, (Cmp) titanPredicate, ((Instant) value).toEpochMilli()));
        } else if (value instanceof Boolean) {
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on boolean types: " + titanPredicate);
            int intValue;
            switch((Cmp) titanPredicate) {
                case EQUAL:
                    intValue = ((Boolean) value) ? 1 : 0;
                    params.addFilter(NumericRangeFilter.newIntRange(key, intValue, intValue, true, true));
                    break;
                case NOT_EQUAL:
                    intValue = ((Boolean) value) ? 0 : 1;
                    params.addFilter(NumericRangeFilter.newIntRange(key, intValue, intValue, true, true));
                    break;
                default:
                    throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
            }
        } else if (value instanceof UUID) {
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on UUID types: " + titanPredicate);
            if (titanPredicate == Cmp.EQUAL) {
                params.addFilter(new TermsFilter(new Term(key, value.toString())));
            } else if (titanPredicate == Cmp.NOT_EQUAL) {
                BooleanFilter q = new BooleanFilter();
                q.add(new TermsFilter(new Term(key, value.toString())), BooleanClause.Occur.MUST_NOT);
                params.addFilter(q);
            } else {
                throw new IllegalArgumentException("Relation is not supported for UUID type: " + titanPredicate);
            }
        } else {
            throw new IllegalArgumentException("Unsupported type: " + value);
        }
    } else if (condition instanceof Not) {
        SearchParams childParams = convertQuery(((Not) condition).getChild(), informations);
        params.addParams(childParams, BooleanClause.Occur.MUST_NOT);
    } else if (condition instanceof And) {
        for (Condition c : condition.getChildren()) {
            SearchParams childParams = convertQuery(c, informations);
            params.addParams(childParams, BooleanClause.Occur.MUST);
        }
    } else if (condition instanceof Or) {
        for (Condition c : condition.getChildren()) {
            SearchParams childParams = convertQuery(c, informations);
            params.addParams(childParams, BooleanClause.Occur.SHOULD);
        }
    } else
        throw new IllegalArgumentException("Invalid condition: " + condition);
    return params;
}
Also used : BooleanFilter(org.apache.lucene.queries.BooleanFilter) Shape(com.spatial4j.core.shape.Shape) TermsFilter(org.apache.lucene.queries.TermsFilter) Mapping(com.thinkaurelius.titan.core.schema.Mapping) SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Instant(java.time.Instant) TitanPredicate(com.thinkaurelius.titan.graphdb.query.TitanPredicate)

Aggregations

Shape (com.spatial4j.core.shape.Shape)1 Mapping (com.thinkaurelius.titan.core.schema.Mapping)1 TitanPredicate (com.thinkaurelius.titan.graphdb.query.TitanPredicate)1 Instant (java.time.Instant)1 BooleanFilter (org.apache.lucene.queries.BooleanFilter)1 TermsFilter (org.apache.lucene.queries.TermsFilter)1 SpatialArgs (org.apache.lucene.spatial.query.SpatialArgs)1