Search in sources :

Example 1 with TitanElement

use of com.thinkaurelius.titan.core.TitanElement in project titan by thinkaurelius.

the class TitanGraphTest method evaluateQuery.

public static void evaluateQuery(TitanGraphQuery query, ElementCategory resultType, int expectedResults, boolean[] subQuerySpecs, Map<PropertyKey, Order> orderMap, String... intersectingIndexes) {
    if (intersectingIndexes == null)
        intersectingIndexes = new String[0];
    SimpleQueryProfiler profiler = new SimpleQueryProfiler();
    ((GraphCentricQueryBuilder) query).profiler(profiler);
    Iterable<? extends TitanElement> result;
    switch(resultType) {
        case PROPERTY:
            result = query.properties();
            break;
        case EDGE:
            result = query.edges();
            break;
        case VERTEX:
            result = query.vertices();
            break;
        default:
            throw new AssertionError();
    }
    OrderList orders = profiler.getAnnotation(QueryProfiler.ORDERS_ANNOTATION);
    //Check elements and that they are returned in the correct order
    int no = 0;
    TitanElement previous = null;
    for (TitanElement e : result) {
        assertNotNull(e);
        no++;
        if (previous != null && !orders.isEmpty()) {
            assertTrue(orders.compare(previous, e) <= 0);
        }
        previous = e;
    }
    assertEquals(expectedResults, no);
    //Check OrderList of query
    assertNotNull(orders);
    assertEquals(orderMap.size(), orders.size());
    for (int i = 0; i < orders.size(); i++) {
        assertEquals(orderMap.get(orders.getKey(i)), orders.getOrder(i));
    }
    for (PropertyKey key : orderMap.keySet()) assertTrue(orders.containsKey(key));
    //Check subqueries
    SimpleQueryProfiler subp = Iterables.getOnlyElement(Iterables.filter(profiler, p -> !p.getGroupName().equals(QueryProfiler.OPTIMIZATION)));
    if (subQuerySpecs.length == 2) {
        //0=>fitted, 1=>ordered
        assertEquals(subQuerySpecs[0], (Boolean) subp.getAnnotation(QueryProfiler.FITTED_ANNOTATION));
        assertEquals(subQuerySpecs[1], (Boolean) subp.getAnnotation(QueryProfiler.ORDERED_ANNOTATION));
    }
    Set<String> indexNames = new HashSet<>();
    int indexQueries = 0;
    boolean fullscan = false;
    for (SimpleQueryProfiler indexp : subp) {
        if (indexp.getAnnotation(QueryProfiler.FULLSCAN_ANNOTATION) != null) {
            fullscan = true;
        } else {
            indexNames.add(indexp.getAnnotation(QueryProfiler.INDEX_ANNOTATION));
            indexQueries++;
        }
    }
    if (indexQueries > 0)
        assertFalse(fullscan);
    if (fullscan)
        assertTrue(intersectingIndexes.length == 0);
    assertEquals(intersectingIndexes.length, indexQueries);
    assertEquals(Sets.newHashSet(intersectingIndexes), indexNames);
}
Also used : BrittleTests(com.thinkaurelius.titan.testcategory.BrittleTests) StandardTitanTx(com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx) Arrays(java.util.Arrays) EdgeSerializer(com.thinkaurelius.titan.graphdb.database.EdgeSerializer) GraphOfTheGodsFactory(com.thinkaurelius.titan.example.GraphOfTheGodsFactory) PropertyKey(com.thinkaurelius.titan.core.PropertyKey) BasicVertexCentricQueryBuilder(com.thinkaurelius.titan.graphdb.query.vertex.BasicVertexCentricQueryBuilder) TransactionId(com.thinkaurelius.titan.core.log.TransactionId) Change(com.thinkaurelius.titan.core.log.Change) BaseVertexLabel(com.thinkaurelius.titan.graphdb.types.system.BaseVertexLabel) EdgeLabel(com.thinkaurelius.titan.core.EdgeLabel) Cardinality.single(org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality.single) Duration(java.time.Duration) Map(java.util.Map) ManagementUtil(com.thinkaurelius.titan.core.util.ManagementUtil) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) Metrics(org.apache.tinkerpop.gremlin.process.traversal.util.Metrics) EnumSet(java.util.EnumSet) InternalRelationType(com.thinkaurelius.titan.graphdb.internal.InternalRelationType) TitanVertex(com.thinkaurelius.titan.core.TitanVertex) ChangeState(com.thinkaurelius.titan.core.log.ChangeState) SimpleQueryProfiler(com.thinkaurelius.titan.graphdb.query.profile.SimpleQueryProfiler) ConfigOption(com.thinkaurelius.titan.diskstorage.configuration.ConfigOption) KCVSLog(com.thinkaurelius.titan.diskstorage.log.kcvs.KCVSLog) SpecialInt(com.thinkaurelius.titan.graphdb.serializer.SpecialInt) EnumMap(java.util.EnumMap) Order.decr(org.apache.tinkerpop.gremlin.process.traversal.Order.decr) Set(java.util.Set) ConsistencyModifier(com.thinkaurelius.titan.core.schema.ConsistencyModifier) ImplicitKey(com.thinkaurelius.titan.graphdb.types.system.ImplicitKey) Vertex(org.apache.tinkerpop.gremlin.structure.Vertex) Mapping(com.thinkaurelius.titan.core.schema.Mapping) Category(org.junit.experimental.categories.Category) StandardEdgeLabelMaker(com.thinkaurelius.titan.graphdb.types.StandardEdgeLabelMaker) CountDownLatch(java.util.concurrent.CountDownLatch) IndexRemoveJob(com.thinkaurelius.titan.graphdb.olap.job.IndexRemoveJob) TitanGraphStep(com.thinkaurelius.titan.graphdb.tinkerpop.optimize.TitanGraphStep) IndexRepairJob(com.thinkaurelius.titan.graphdb.olap.job.IndexRepairJob) GraphTraversalSource(org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource) Iterables(com.google.common.collect.Iterables) StartStep(org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep) TitanVertexQuery(com.thinkaurelius.titan.core.TitanVertexQuery) Message(com.thinkaurelius.titan.diskstorage.log.Message) Cardinality(com.thinkaurelius.titan.core.Cardinality) LogProcessorFramework(com.thinkaurelius.titan.core.log.LogProcessorFramework) QueryProfiler(com.thinkaurelius.titan.graphdb.query.profile.QueryProfiler) ArrayList(java.util.ArrayList) OrderList(com.thinkaurelius.titan.graphdb.internal.OrderList) LogTxMeta(com.thinkaurelius.titan.graphdb.database.log.LogTxMeta) Lists(com.google.common.collect.Lists) GraphDatabaseConfiguration(com.thinkaurelius.titan.graphdb.configuration.GraphDatabaseConfiguration) LogTxStatus(com.thinkaurelius.titan.graphdb.database.log.LogTxStatus) GraphStep(org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GraphStep) TitanAssert(com.thinkaurelius.titan.testutil.TitanAssert) MessageReader(com.thinkaurelius.titan.diskstorage.log.MessageReader) PropertyKeyDefinition(com.thinkaurelius.titan.graphdb.schema.PropertyKeyDefinition) TransactionRecovery(com.thinkaurelius.titan.core.log.TransactionRecovery) VertexLabelDefinition(com.thinkaurelius.titan.graphdb.schema.VertexLabelDefinition) TitanGraphIndex(com.thinkaurelius.titan.core.schema.TitanGraphIndex) Test(org.junit.Test) T(org.apache.tinkerpop.gremlin.structure.T) TitanManagement(com.thinkaurelius.titan.core.schema.TitanManagement) ExecutionException(java.util.concurrent.ExecutionException) Direction(org.apache.tinkerpop.gremlin.structure.Direction) ChronoUnit(java.time.temporal.ChronoUnit) Cmp(com.thinkaurelius.titan.core.attribute.Cmp) Traversal(org.apache.tinkerpop.gremlin.process.traversal.Traversal) TransactionLogHeader(com.thinkaurelius.titan.graphdb.database.log.TransactionLogHeader) Preconditions(com.google.common.base.Preconditions) TraversalMetrics(org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics) Assert(org.junit.Assert) Geoshape(com.thinkaurelius.titan.core.attribute.Geoshape) TitanVertexStep(com.thinkaurelius.titan.graphdb.tinkerpop.optimize.TitanVertexStep) TitanSchemaType(com.thinkaurelius.titan.core.schema.TitanSchemaType) Multiplicity(com.thinkaurelius.titan.core.Multiplicity) LoggerFactory(org.slf4j.LoggerFactory) SchemaStatus(com.thinkaurelius.titan.core.schema.SchemaStatus) Order(com.thinkaurelius.titan.graphdb.internal.Order) Random(java.util.Random) Order.incr(org.apache.tinkerpop.gremlin.process.traversal.Order.incr) RelationCategory(com.thinkaurelius.titan.graphdb.internal.RelationCategory) SpecialIntSerializer(com.thinkaurelius.titan.graphdb.serializer.SpecialIntSerializer) SchemaViolationException(com.thinkaurelius.titan.core.SchemaViolationException) TitanFactory(com.thinkaurelius.titan.core.TitanFactory) ChangeProcessor(com.thinkaurelius.titan.core.log.ChangeProcessor) VertexLabel(com.thinkaurelius.titan.core.VertexLabel) ElementCategory(com.thinkaurelius.titan.graphdb.internal.ElementCategory) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TimestampProvider(com.thinkaurelius.titan.diskstorage.util.time.TimestampProvider) P(org.apache.tinkerpop.gremlin.process.traversal.P) RelationIdentifier(com.thinkaurelius.titan.graphdb.relations.RelationIdentifier) TitanPropertiesStep(com.thinkaurelius.titan.graphdb.tinkerpop.optimize.TitanPropertiesStep) ImmutableMap(com.google.common.collect.ImmutableMap) BackendException(com.thinkaurelius.titan.diskstorage.BackendException) Serializer(com.thinkaurelius.titan.graphdb.database.serialize.Serializer) TitanConfigurationException(com.thinkaurelius.titan.core.TitanConfigurationException) SchemaAction(com.thinkaurelius.titan.core.schema.SchemaAction) Instant(java.time.Instant) TitanCleanup(com.thinkaurelius.titan.core.util.TitanCleanup) Sets(com.google.common.collect.Sets) List(java.util.List) LocalStep(org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalStep) TitanVertexProperty(com.thinkaurelius.titan.core.TitanVertexProperty) TitanTransaction(com.thinkaurelius.titan.core.TitanTransaction) TitanElement(com.thinkaurelius.titan.core.TitanElement) RelationType(com.thinkaurelius.titan.core.RelationType) StandardTransactionLogProcessor(com.thinkaurelius.titan.graphdb.log.StandardTransactionLogProcessor) StandardTitanGraph(com.thinkaurelius.titan.graphdb.database.StandardTitanGraph) TitanGraph(com.thinkaurelius.titan.core.TitanGraph) EdgeLabelDefinition(com.thinkaurelius.titan.graphdb.schema.EdgeLabelDefinition) WriteConfiguration(com.thinkaurelius.titan.diskstorage.configuration.WriteConfiguration) Log(com.thinkaurelius.titan.diskstorage.log.Log) GraphCentricQueryBuilder(com.thinkaurelius.titan.graphdb.query.graph.GraphCentricQueryBuilder) TitanException(com.thinkaurelius.titan.core.TitanException) ManagementSystem(com.thinkaurelius.titan.graphdb.database.management.ManagementSystem) StandardPropertyKeyMaker(com.thinkaurelius.titan.graphdb.types.StandardPropertyKeyMaker) Iterators(com.google.common.collect.Iterators) OrderGlobalStep(org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep) HashSet(java.util.HashSet) VertexProperty(org.apache.tinkerpop.gremlin.structure.VertexProperty) ImmutableList(com.google.common.collect.ImmutableList) RelationTypeIndex(com.thinkaurelius.titan.core.schema.RelationTypeIndex) TitanEdge(com.thinkaurelius.titan.core.TitanEdge) VertexList(com.thinkaurelius.titan.core.VertexList) Edge(org.apache.tinkerpop.gremlin.structure.Edge) SchemaContainer(com.thinkaurelius.titan.graphdb.schema.SchemaContainer) Contain(com.thinkaurelius.titan.core.attribute.Contain) TitanGraphQuery(com.thinkaurelius.titan.core.TitanGraphQuery) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__(org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__) GraphTraversal(org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal) TestGraphConfigs(com.thinkaurelius.titan.testutil.TestGraphConfigs) Step(org.apache.tinkerpop.gremlin.process.traversal.Step) TimeUnit(java.util.concurrent.TimeUnit) ReadMarker(com.thinkaurelius.titan.diskstorage.log.ReadMarker) ConfigElement(com.thinkaurelius.titan.diskstorage.configuration.ConfigElement) ScanMetrics(com.thinkaurelius.titan.diskstorage.keycolumnvalue.scan.ScanMetrics) TraversalFilterStep(org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep) GraphCentricQueryBuilder(com.thinkaurelius.titan.graphdb.query.graph.GraphCentricQueryBuilder) SimpleQueryProfiler(com.thinkaurelius.titan.graphdb.query.profile.SimpleQueryProfiler) TitanElement(com.thinkaurelius.titan.core.TitanElement) OrderList(com.thinkaurelius.titan.graphdb.internal.OrderList) PropertyKey(com.thinkaurelius.titan.core.PropertyKey) HashSet(java.util.HashSet)

Example 2 with TitanElement

use of com.thinkaurelius.titan.core.TitanElement in project titan by thinkaurelius.

the class TitanGraphTest method evaluateQuery.

public static void evaluateQuery(TitanVertexQuery query, RelationCategory resultType, int expectedResults, int numSubQueries, boolean[] subQuerySpecs, Map<PropertyKey, Order> orderMap) {
    SimpleQueryProfiler profiler = new SimpleQueryProfiler();
    ((BasicVertexCentricQueryBuilder) query).profiler(profiler);
    Iterable<? extends TitanElement> result;
    switch(resultType) {
        case PROPERTY:
            result = query.properties();
            break;
        case EDGE:
            result = query.edges();
            break;
        case RELATION:
            result = query.relations();
            break;
        default:
            throw new AssertionError();
    }
    OrderList orders = profiler.getAnnotation(QueryProfiler.ORDERS_ANNOTATION);
    //Check elements and that they are returned in the correct order
    int no = 0;
    TitanElement previous = null;
    for (TitanElement e : result) {
        assertNotNull(e);
        no++;
        if (previous != null && !orders.isEmpty()) {
            assertTrue(orders.compare(previous, e) <= 0);
        }
        previous = e;
    }
    assertEquals(expectedResults, no);
    //Check OrderList of query
    assertNotNull(orders);
    assertEquals(orderMap.size(), orders.size());
    for (int i = 0; i < orders.size(); i++) {
        assertEquals(orderMap.get(orders.getKey(i)), orders.getOrder(i));
    }
    for (PropertyKey key : orderMap.keySet()) assertTrue(orders.containsKey(key));
    //Check subqueries
    assertEquals(1, (Number) profiler.getAnnotation(QueryProfiler.NUMVERTICES_ANNOTATION));
    int subQueryCounter = 0;
    for (SimpleQueryProfiler subProfiler : profiler) {
        assertNotNull(subProfiler);
        if (subProfiler.getGroupName().equals(QueryProfiler.OPTIMIZATION))
            continue;
        if (subQuerySpecs.length == 2) {
            //0=>fitted, 1=>ordered
            assertEquals(subQuerySpecs[0], (Boolean) subProfiler.getAnnotation(QueryProfiler.FITTED_ANNOTATION));
            assertEquals(subQuerySpecs[1], (Boolean) subProfiler.getAnnotation(QueryProfiler.ORDERED_ANNOTATION));
        }
        //assertEquals(1,Iterables.size(subProfiler)); This only applies if a disk call is necessary
        subQueryCounter++;
    }
    assertEquals(numSubQueries, subQueryCounter);
}
Also used : BasicVertexCentricQueryBuilder(com.thinkaurelius.titan.graphdb.query.vertex.BasicVertexCentricQueryBuilder) TitanElement(com.thinkaurelius.titan.core.TitanElement) OrderList(com.thinkaurelius.titan.graphdb.internal.OrderList) SimpleQueryProfiler(com.thinkaurelius.titan.graphdb.query.profile.SimpleQueryProfiler) PropertyKey(com.thinkaurelius.titan.core.PropertyKey)

Example 3 with TitanElement

use of com.thinkaurelius.titan.core.TitanElement in project titan by thinkaurelius.

the class SolrIndex method buildQueryFilter.

public String buildQueryFilter(Condition<TitanElement> condition, KeyInformation.StoreRetriever informations) {
    if (condition instanceof PredicateCondition) {
        PredicateCondition<String, TitanElement> atom = (PredicateCondition<String, TitanElement>) condition;
        Object value = atom.getValue();
        String key = atom.getKey();
        TitanPredicate titanPredicate = atom.getPredicate();
        if (value instanceof Number) {
            String queryValue = escapeValue(value);
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
            Cmp numRel = (Cmp) titanPredicate;
            switch(numRel) {
                case EQUAL:
                    return (key + ":" + queryValue);
                case NOT_EQUAL:
                    return ("-" + key + ":" + queryValue);
                case LESS_THAN:
                    //use right curly to mean up to but not including value
                    return (key + ":[* TO " + queryValue + "}");
                case LESS_THAN_EQUAL:
                    return (key + ":[* TO " + queryValue + "]");
                case GREATER_THAN:
                    //use left curly to mean greater than but not including value
                    return (key + ":{" + queryValue + " TO *]");
                case GREATER_THAN_EQUAL:
                    return (key + ":[" + queryValue + " TO *]");
                default:
                    throw new IllegalArgumentException("Unexpected relation: " + numRel);
            }
        } else if (value instanceof String) {
            Mapping map = getStringMapping(informations.get(key));
            assert map == Mapping.TEXT || map == Mapping.STRING;
            if (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);
            //Special case
            if (titanPredicate == Text.CONTAINS) {
                //e.g. - if terms tomorrow and world were supplied, and fq=text:(tomorrow  world)
                //sample data set would return 2 documents: one where text = Tomorrow is the World,
                //and the second where text = Hello World. Hence, we are decomposing the query string
                //and building an AND query explicitly because we need AND semantics
                value = ((String) value).toLowerCase();
                List<String> terms = Text.tokenize((String) value);
                if (terms.isEmpty()) {
                    return "";
                } else if (terms.size() == 1) {
                    return (key + ":(" + escapeValue(terms.get(0)) + ")");
                } else {
                    And<TitanElement> andTerms = new And<TitanElement>();
                    for (String term : terms) {
                        andTerms.add(new PredicateCondition<String, TitanElement>(key, titanPredicate, term));
                    }
                    return buildQueryFilter(andTerms, informations);
                }
            }
            if (titanPredicate == Text.PREFIX || titanPredicate == Text.CONTAINS_PREFIX) {
                return (key + ":" + escapeValue(value) + "*");
            } else if (titanPredicate == Text.REGEX || titanPredicate == Text.CONTAINS_REGEX) {
                return (key + ":/" + value + "/");
            } else if (titanPredicate == Cmp.EQUAL) {
                return (key + ":\"" + escapeValue(value) + "\"");
            } else if (titanPredicate == Cmp.NOT_EQUAL) {
                return ("-" + key + ":\"" + escapeValue(value) + "\"");
            } else {
                throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
            }
        } else if (value instanceof Geoshape) {
            Geoshape geo = (Geoshape) value;
            if (geo.getType() == Geoshape.Type.CIRCLE) {
                Geoshape.Point center = geo.getPoint();
                return ("{!geofilt sfield=" + key + " pt=" + center.getLatitude() + "," + center.getLongitude() + " d=" + geo.getRadius() + //distance in kilometers
                "} distErrPct=0");
            } else if (geo.getType() == Geoshape.Type.BOX) {
                Geoshape.Point southwest = geo.getPoint(0);
                Geoshape.Point northeast = geo.getPoint(1);
                return (key + ":[" + southwest.getLatitude() + "," + southwest.getLongitude() + " TO " + northeast.getLatitude() + "," + northeast.getLongitude() + "]");
            } else if (geo.getType() == Geoshape.Type.POLYGON) {
                List<Geoshape.Point> coordinates = getPolygonPoints(geo);
                StringBuilder poly = new StringBuilder(key + ":\"IsWithin(POLYGON((");
                for (Geoshape.Point coordinate : coordinates) {
                    poly.append(coordinate.getLongitude()).append(" ").append(coordinate.getLatitude()).append(", ");
                }
                //close the polygon with the first coordinate
                poly.append(coordinates.get(0).getLongitude()).append(" ").append(coordinates.get(0).getLatitude());
                poly.append(")))\" distErrPct=0");
                return (poly.toString());
            }
        } else if (value instanceof Date || value instanceof Instant) {
            String s = value.toString();
            String queryValue = escapeValue(value instanceof Date ? toIsoDate((Date) value) : value.toString());
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
            Cmp numRel = (Cmp) titanPredicate;
            switch(numRel) {
                case EQUAL:
                    return (key + ":" + queryValue);
                case NOT_EQUAL:
                    return ("-" + key + ":" + queryValue);
                case LESS_THAN:
                    //use right curly to mean up to but not including value
                    return (key + ":[* TO " + queryValue + "}");
                case LESS_THAN_EQUAL:
                    return (key + ":[* TO " + queryValue + "]");
                case GREATER_THAN:
                    //use left curly to mean greater than but not including value
                    return (key + ":{" + queryValue + " TO *]");
                case GREATER_THAN_EQUAL:
                    return (key + ":[" + queryValue + " TO *]");
                default:
                    throw new IllegalArgumentException("Unexpected relation: " + numRel);
            }
        } else if (value instanceof Boolean) {
            Cmp numRel = (Cmp) titanPredicate;
            String queryValue = escapeValue(value);
            switch(numRel) {
                case EQUAL:
                    return (key + ":" + queryValue);
                case NOT_EQUAL:
                    return ("-" + key + ":" + queryValue);
                default:
                    throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
            }
        } else if (value instanceof UUID) {
            if (titanPredicate == Cmp.EQUAL) {
                return (key + ":\"" + escapeValue(value) + "\"");
            } else if (titanPredicate == Cmp.NOT_EQUAL) {
                return ("-" + key + ":\"" + escapeValue(value) + "\"");
            } else {
                throw new IllegalArgumentException("Relation is not supported for uuid value: " + titanPredicate);
            }
        } else
            throw new IllegalArgumentException("Unsupported type: " + value);
    } else if (condition instanceof Not) {
        String sub = buildQueryFilter(((Not) condition).getChild(), informations);
        if (StringUtils.isNotBlank(sub))
            return "-(" + sub + ")";
        else
            return "";
    } else if (condition instanceof And) {
        int numChildren = ((And) condition).size();
        StringBuilder sb = new StringBuilder();
        for (Condition<TitanElement> c : condition.getChildren()) {
            String sub = buildQueryFilter(c, informations);
            if (StringUtils.isBlank(sub))
                continue;
            // b. expression is a single statement in the AND.
            if (!sub.startsWith("-") && numChildren > 1)
                sb.append("+");
            sb.append(sub).append(" ");
        }
        return sb.toString();
    } else if (condition instanceof Or) {
        StringBuilder sb = new StringBuilder();
        int element = 0;
        for (Condition<TitanElement> c : condition.getChildren()) {
            String sub = buildQueryFilter(c, informations);
            if (StringUtils.isBlank(sub))
                continue;
            if (element == 0)
                sb.append("(");
            else
                sb.append(" OR ");
            sb.append(sub);
            element++;
        }
        if (element > 0)
            sb.append(")");
        return sb.toString();
    } else {
        throw new IllegalArgumentException("Invalid condition: " + condition);
    }
    return null;
}
Also used : Mapping(com.thinkaurelius.titan.core.schema.Mapping) TitanElement(com.thinkaurelius.titan.core.TitanElement) Instant(java.time.Instant) TitanPredicate(com.thinkaurelius.titan.graphdb.query.TitanPredicate)

Example 4 with TitanElement

use of com.thinkaurelius.titan.core.TitanElement in project atlas by apache.

the class Solr5Index method buildQueryFilter.

public String buildQueryFilter(Condition<TitanElement> condition, KeyInformation.StoreRetriever informations) {
    if (condition instanceof PredicateCondition) {
        PredicateCondition<String, TitanElement> atom = (PredicateCondition<String, TitanElement>) condition;
        Object value = atom.getValue();
        String key = atom.getKey();
        TitanPredicate titanPredicate = atom.getPredicate();
        if (value instanceof Number) {
            String queryValue = escapeValue(value);
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
            Cmp numRel = (Cmp) titanPredicate;
            switch(numRel) {
                case EQUAL:
                    return (key + ":" + queryValue);
                case NOT_EQUAL:
                    return ("-" + key + ":" + queryValue);
                case LESS_THAN:
                    // use right curly to mean up to but not including value
                    return (key + ":[* TO " + queryValue + "}");
                case LESS_THAN_EQUAL:
                    return (key + ":[* TO " + queryValue + "]");
                case GREATER_THAN:
                    // use left curly to mean greater than but not including value
                    return (key + ":{" + queryValue + " TO *]");
                case GREATER_THAN_EQUAL:
                    return (key + ":[" + queryValue + " TO *]");
                default:
                    throw new IllegalArgumentException("Unexpected relation: " + numRel);
            }
        } else if (value instanceof String) {
            Mapping map = getStringMapping(informations.get(key));
            assert map == TEXT || map == STRING;
            if (map == TEXT && !titanPredicate.toString().startsWith("CONTAINS"))
                throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
            if (map == STRING && titanPredicate.toString().startsWith("CONTAINS"))
                throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
            // Special case
            if (titanPredicate == Text.CONTAINS) {
                // e.g. - if terms tomorrow and world were supplied, and fq=text:(tomorrow  world)
                // sample data set would return 2 documents: one where text = Tomorrow is the World,
                // and the second where text = Hello World. Hence, we are decomposing the query string
                // and building an AND query explicitly because we need AND semantics
                value = ((String) value).toLowerCase();
                List<String> terms = Text.tokenize((String) value);
                if (terms.isEmpty()) {
                    return "";
                } else if (terms.size() == 1) {
                    return (key + ":(" + escapeValue(terms.get(0)) + ")");
                } else {
                    And<TitanElement> andTerms = new And<>();
                    for (String term : terms) {
                        andTerms.add(new PredicateCondition<>(key, titanPredicate, term));
                    }
                    return buildQueryFilter(andTerms, informations);
                }
            }
            if (titanPredicate == Text.PREFIX || titanPredicate == Text.CONTAINS_PREFIX) {
                return (key + ":" + escapeValue(value) + "*");
            } else if (titanPredicate == Text.REGEX || titanPredicate == Text.CONTAINS_REGEX) {
                return (key + ":/" + value + "/");
            } else if (titanPredicate == EQUAL) {
                return (key + ":\"" + escapeValue(value) + "\"");
            } else if (titanPredicate == NOT_EQUAL) {
                return ("-" + key + ":\"" + escapeValue(value) + "\"");
            } else {
                throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
            }
        } else if (value instanceof Geoshape) {
            Geoshape geo = (Geoshape) value;
            if (geo.getType() == Geoshape.Type.CIRCLE) {
                Geoshape.Point center = geo.getPoint();
                return ("{!geofilt sfield=" + key + " pt=" + center.getLatitude() + "," + center.getLongitude() + " d=" + geo.getRadius() + // distance in kilometers
                "} distErrPct=0");
            } else if (geo.getType() == Geoshape.Type.BOX) {
                Geoshape.Point southwest = geo.getPoint(0);
                Geoshape.Point northeast = geo.getPoint(1);
                return (key + ":[" + southwest.getLatitude() + "," + southwest.getLongitude() + " TO " + northeast.getLatitude() + "," + northeast.getLongitude() + "]");
            } else if (geo.getType() == Geoshape.Type.POLYGON) {
                List<Geoshape.Point> coordinates = getPolygonPoints(geo);
                StringBuilder poly = new StringBuilder(key + ":\"IsWithin(POLYGON((");
                for (Geoshape.Point coordinate : coordinates) {
                    poly.append(coordinate.getLongitude()).append(" ").append(coordinate.getLatitude()).append(", ");
                }
                // close the polygon with the first coordinate
                poly.append(coordinates.get(0).getLongitude()).append(" ").append(coordinates.get(0).getLatitude());
                poly.append(")))\" distErrPct=0");
                return (poly.toString());
            }
        } else if (value instanceof Date) {
            String queryValue = escapeValue(toIsoDate((Date) value));
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on date types: " + titanPredicate);
            Cmp numRel = (Cmp) titanPredicate;
            switch(numRel) {
                case EQUAL:
                    return (key + ":" + queryValue);
                case NOT_EQUAL:
                    return ("-" + key + ":" + queryValue);
                case LESS_THAN:
                    // use right curly to mean up to but not including value
                    return (key + ":[* TO " + queryValue + "}");
                case LESS_THAN_EQUAL:
                    return (key + ":[* TO " + queryValue + "]");
                case GREATER_THAN:
                    // use left curly to mean greater than but not including value
                    return (key + ":{" + queryValue + " TO *]");
                case GREATER_THAN_EQUAL:
                    return (key + ":[" + queryValue + " TO *]");
                default:
                    throw new IllegalArgumentException("Unexpected relation: " + numRel);
            }
        } else if (value instanceof Boolean) {
            Cmp numRel = (Cmp) titanPredicate;
            String queryValue = escapeValue(value);
            switch(numRel) {
                case EQUAL:
                    return (key + ":" + queryValue);
                case NOT_EQUAL:
                    return ("-" + key + ":" + queryValue);
                default:
                    throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
            }
        } else if (value instanceof UUID) {
            if (titanPredicate == EQUAL) {
                return (key + ":\"" + escapeValue(value) + "\"");
            } else if (titanPredicate == NOT_EQUAL) {
                return ("-" + key + ":\"" + escapeValue(value) + "\"");
            } else {
                throw new IllegalArgumentException("Relation is not supported for uuid value: " + titanPredicate);
            }
        } else
            throw new IllegalArgumentException("Unsupported type: " + value);
    } else if (condition instanceof Not) {
        String sub = buildQueryFilter(((Not) condition).getChild(), informations);
        if (StringUtils.isNotBlank(sub))
            return "-(" + sub + ")";
        else
            return "";
    } else if (condition instanceof And) {
        int numChildren = ((And) condition).size();
        StringBuilder sb = new StringBuilder();
        for (Condition<TitanElement> c : condition.getChildren()) {
            String sub = buildQueryFilter(c, informations);
            if (StringUtils.isBlank(sub))
                continue;
            // b. expression is a single statement in the AND.
            if (!sub.startsWith("-") && numChildren > 1)
                sb.append("+");
            sb.append(sub).append(" ");
        }
        return sb.toString();
    } else if (condition instanceof Or) {
        StringBuilder sb = new StringBuilder();
        int element = 0;
        for (Condition<TitanElement> c : condition.getChildren()) {
            String sub = buildQueryFilter(c, informations);
            if (StringUtils.isBlank(sub))
                continue;
            if (element == 0)
                sb.append("(");
            else
                sb.append(" OR ");
            sb.append(sub);
            element++;
        }
        if (element > 0)
            sb.append(")");
        return sb.toString();
    } else {
        throw new IllegalArgumentException("Invalid condition: " + condition);
    }
    return null;
}
Also used : Or(com.thinkaurelius.titan.graphdb.query.condition.Or) Mapping(com.thinkaurelius.titan.core.schema.Mapping) TitanElement(com.thinkaurelius.titan.core.TitanElement) List(java.util.List) ArrayList(java.util.ArrayList) UUID(java.util.UUID) Condition(com.thinkaurelius.titan.graphdb.query.condition.Condition) PredicateCondition(com.thinkaurelius.titan.graphdb.query.condition.PredicateCondition) PredicateCondition(com.thinkaurelius.titan.graphdb.query.condition.PredicateCondition) Cmp(com.thinkaurelius.titan.core.attribute.Cmp) Geoshape(com.thinkaurelius.titan.core.attribute.Geoshape) Date(java.util.Date) Not(com.thinkaurelius.titan.graphdb.query.condition.Not) And(com.thinkaurelius.titan.graphdb.query.condition.And) TitanPredicate(com.thinkaurelius.titan.graphdb.query.TitanPredicate)

Example 5 with TitanElement

use of com.thinkaurelius.titan.core.TitanElement in project titan by thinkaurelius.

the class StandardTransactionLogProcessor method fixSecondaryFailure.

private void fixSecondaryFailure(final StandardTransactionId txId, final TxEntry entry) {
    logRecoveryMsg("Attempting to repair partially failed transaction [%s]", txId);
    if (entry.entry == null) {
        logRecoveryMsg("Trying to repair expired or unpersisted transaction [%s] (Ignore in startup)", txId);
        return;
    }
    boolean userLogFailure = true;
    boolean secIndexFailure = true;
    final Predicate<String> isFailedIndex;
    final TransactionLogHeader.Entry commitEntry = entry.entry;
    final TransactionLogHeader.SecondaryFailures secFail = entry.failures;
    if (secFail != null) {
        userLogFailure = secFail.userLogFailure;
        secIndexFailure = !secFail.failedIndexes.isEmpty();
        isFailedIndex = new Predicate<String>() {

            @Override
            public boolean apply(@Nullable String s) {
                return secFail.failedIndexes.contains(s);
            }
        };
    } else {
        isFailedIndex = Predicates.alwaysTrue();
    }
    // I) Restore external indexes
    if (secIndexFailure) {
        //1) Collect all elements (vertices and relations) and the indexes for which they need to be restored
        final SetMultimap<String, IndexRestore> indexRestores = HashMultimap.create();
        BackendOperation.execute(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                StandardTitanTx tx = (StandardTitanTx) graph.newTransaction();
                try {
                    for (TransactionLogHeader.Modification modification : commitEntry.getContentAsModifications(serializer)) {
                        InternalRelation rel = ModificationDeserializer.parseRelation(modification, tx);
                        //Collect affected vertex indexes
                        for (MixedIndexType index : getMixedIndexes(rel.getType())) {
                            if (index.getElement() == ElementCategory.VERTEX && isFailedIndex.apply(index.getBackingIndexName())) {
                                assert rel.isProperty();
                                indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.getVertex(0).longId(), ElementCategory.VERTEX, getIndexId(index)));
                            }
                        }
                        //See if relation itself is affected
                        for (RelationType relType : rel.getPropertyKeysDirect()) {
                            for (MixedIndexType index : getMixedIndexes(relType)) {
                                if (index.getElement().isInstance(rel) && isFailedIndex.apply(index.getBackingIndexName())) {
                                    assert rel.id() instanceof RelationIdentifier;
                                    indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.id(), ElementCategory.getByClazz(rel.getClass()), getIndexId(index)));
                                }
                            }
                        }
                    }
                } finally {
                    if (tx.isOpen())
                        tx.rollback();
                }
                return true;
            }
        }, readTime);
        //2) Restore elements per backing index
        for (final String indexName : indexRestores.keySet()) {
            final StandardTitanTx tx = (StandardTitanTx) graph.newTransaction();
            try {
                BackendTransaction btx = tx.getTxHandle();
                final IndexTransaction indexTx = btx.getIndexTransaction(indexName);
                BackendOperation.execute(new Callable<Boolean>() {

                    @Override
                    public Boolean call() throws Exception {
                        Map<String, Map<String, List<IndexEntry>>> restoredDocs = Maps.newHashMap();
                        for (IndexRestore restore : indexRestores.get(indexName)) {
                            TitanSchemaVertex indexV = (TitanSchemaVertex) tx.getVertex(restore.indexId);
                            MixedIndexType index = (MixedIndexType) indexV.asIndexType();
                            TitanElement element = restore.retrieve(tx);
                            if (element != null) {
                                graph.getIndexSerializer().reindexElement(element, index, restoredDocs);
                            } else {
                                //Element is deleted
                                graph.getIndexSerializer().removeElement(restore.elementId, index, restoredDocs);
                            }
                        }
                        indexTx.restore(restoredDocs);
                        indexTx.commit();
                        return true;
                    }

                    @Override
                    public String toString() {
                        return "IndexMutation";
                    }
                }, persistenceTime);
            } finally {
                if (tx.isOpen())
                    tx.rollback();
            }
        }
    }
    // II) Restore log messages
    final String logTxIdentifier = (String) commitEntry.getMetadata().get(LogTxMeta.LOG_ID);
    if (userLogFailure && logTxIdentifier != null) {
        TransactionLogHeader txHeader = new TransactionLogHeader(txCounter.incrementAndGet(), times.getTime(), times);
        final StaticBuffer userLogContent = txHeader.serializeUserLog(serializer, commitEntry, txId);
        BackendOperation.execute(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                final Log userLog = graph.getBackend().getUserLog(logTxIdentifier);
                Future<Message> env = userLog.add(userLogContent);
                if (env.isDone()) {
                    env.get();
                }
                return true;
            }
        }, persistenceTime);
    }
}
Also used : IndexTransaction(com.thinkaurelius.titan.diskstorage.indexing.IndexTransaction) InternalRelation(com.thinkaurelius.titan.graphdb.internal.InternalRelation) InternalRelationType(com.thinkaurelius.titan.graphdb.internal.InternalRelationType) RelationType(com.thinkaurelius.titan.core.RelationType) TitanElement(com.thinkaurelius.titan.core.TitanElement) List(java.util.List) TransactionLogHeader(com.thinkaurelius.titan.graphdb.database.log.TransactionLogHeader) MixedIndexType(com.thinkaurelius.titan.graphdb.types.MixedIndexType) TitanSchemaVertex(com.thinkaurelius.titan.graphdb.types.vertices.TitanSchemaVertex) RelationIdentifier(com.thinkaurelius.titan.graphdb.relations.RelationIdentifier) StandardTitanTx(com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx) TitanException(com.thinkaurelius.titan.core.TitanException) ExecutionException(java.util.concurrent.ExecutionException) Future(java.util.concurrent.Future) Map(java.util.Map)

Aggregations

TitanElement (com.thinkaurelius.titan.core.TitanElement)6 Mapping (com.thinkaurelius.titan.core.schema.Mapping)4 List (java.util.List)4 Cmp (com.thinkaurelius.titan.core.attribute.Cmp)3 Geoshape (com.thinkaurelius.titan.core.attribute.Geoshape)3 TitanPredicate (com.thinkaurelius.titan.graphdb.query.TitanPredicate)3 ArrayList (java.util.ArrayList)3 PropertyKey (com.thinkaurelius.titan.core.PropertyKey)2 RelationType (com.thinkaurelius.titan.core.RelationType)2 TitanException (com.thinkaurelius.titan.core.TitanException)2 OrderList (com.thinkaurelius.titan.graphdb.internal.OrderList)2 SimpleQueryProfiler (com.thinkaurelius.titan.graphdb.query.profile.SimpleQueryProfiler)2 BasicVertexCentricQueryBuilder (com.thinkaurelius.titan.graphdb.query.vertex.BasicVertexCentricQueryBuilder)2 Instant (java.time.Instant)2 Preconditions (com.google.common.base.Preconditions)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Iterables (com.google.common.collect.Iterables)1 Iterators (com.google.common.collect.Iterators)1 Lists (com.google.common.collect.Lists)1