Chapter 19. Search Predicates and Data Types

This page lists all of the comparison predicates that Titan supports in global graph search and local traversals.

19.1. Compare Predicate

The Compare enum specifies the following self-explanatory comparison predicates used for index query construction and used in the examples above:

  • EQUAL
  • NOT_EQUAL
  • GREATER_THAN
  • GREATER_THAN_EQUAL
  • LESS_THAN
  • LESS_THAN_EQUAL

19.2. Text Predicate

The Text enum specifies the search operator used to query for matching text or string values. We differentiate between two types of predicates:

  • Text search predicates which match against the individual words inside a text string after it has been tokenized. These predicates are not case sensitive.

    • CONTAINS: is true if (at least) one word inside the text string matches the query string
    • CONTAINS_PREFIX: is true if (at least) one word inside the text string begins with the query string
    • CONTAINS_REGEX: is true if (at least) one word inside the text string matches the given regular expression
  • String search predicates which match against the entire string value

    • PREFIX: if the string value starts with the given query string
    • REGEX: if the string value matches the given regular expression in its entirety

See Section 20.1, “Full-Text Search” for more information about full-text and string search.

19.3. Geo Predicate

The Geo enum specifies the geo-location predicate Geo.WITHIN which holds true if one geometric object contains the other.

19.4. Query Examples

The following query examples demonstrate some of the predicates on the tutorial graph.

g.V().has("name", "hercules")
// 2) Find all vertices with an age greater than 50
g.V().has("age", gt(50))
// or find all vertices between 1000 (inclusive) and 5000 (exclusive) years of age and order by increasing age
g.V().has("age", inside(1000, 5000)).order().by("age", incr)
// which returns the same result set as the following query but in reverse order
g.V().has("age", inside(1000, 5000)).order().by("age", decr)
// 3) Find all edges where the place is at most 50 kilometers from the given latitude-longitude pair
g.E().has("place", new P(WITHIN, Geoshape.circle(37.97, 23.72, 50)))
// 4) Find all edges where reason contains the word "loves"
g.E().has("reason", new P(CONTAINS, "loves"))
// or all edges which contain two words (need to chunk into individual words)
g.E().has("reason", new P(CONTAINS, "loves")).has("reason", new P(CONTAINS, "breezes"))
// or all edges which contain words that start with "lov"
g.E().has("reason", new P(CONTAINS_PREFIX, "lov"))
// or all edges which contain words that match the regular expression "br[ez]*s" in their entirety
g.E().has("reason", new P(CONTAINS_REGEX, "br[ez]*s"))
// 5) Find all vertices older than a thousand years and named "saturn"
g.V().has("age", gt(1000)).has("name", "saturn")

19.5. Data Type Support

While Titan’s composite indexes support any data type that can be stored in Titan, the mixed indexes are limited to the following data types.

  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double
  • Decimal
  • Precision
  • String
  • Geoshape
  • Date
  • Instant

Additional data types will be supported in the future.

19.6. Geoshape Data Type

The Geoshape data type supports representing a point, circle or box. However all index backends currently only support indexing points. Geospatial index lookups are only supported via mixed indexes.

To construct a Geoshape use the following methods:

 //lat, lng
Geoshape.point(37.97, 23.72)
//lat, lng, radius in km
Geoshape.circle(37.97, 23.72, 50)
//SW lat, SW lng, NE lat, NE lng
Geoshape.box(37.97, 23.72, 38.97, 24.72)

In addition when importing a graph via GraphSON Point may be represented by:

 //string
"37.97, 23.72"
//list
[37.97, 23.72]
//GeoJSON feature
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}
//GeoJSON geometry
{
  "type": "Point",
  "coordinates": [125.6, 10.1]
}

GeoJSON may be specified as Point, Circle or Polygon. However polygons must form a box. Note that unlike the Titan API GeoJSON specifies coordinates as lng lat.

19.7. Collections

If you are using Elasticsearch then you can index properties with SET and LIST cardinality. For instance:

mgmt = graph.openManagement()
nameProperty = mgmt.makePropertyKey("names").dataType(String.class).cardinality(Cardinality.SET).make()
mgmt.buildIndex("search", Vertex.class).addKey(nameProperty, Mapping.STRING.asParameter()).buildMixedIndex("search")
mgmt.commit()
//Insert a vertex
person = graph.addVertex()
person.property("names", "Robert")
person.property("names", "Bob")
graph.tx().commit()
//Now query it
g.V().has("names", "Bob").count().next() //1
g.V().has("names", "Robert").count().next() //1