Adding index schema
Adding index database schema.
All index schema is based on previously created properties and vertex labels and
added to existing schema with add()
.
Prerequisites
Procedure
-
Create a materialized view index for a global index:
schema.vertexLabel('person').index('byName').materialized().by('name').add()
Identify the vertex label and property key for the index, in the
vertexLabel()
andby()
steps, respectively. In theindex()
step, name the index. Thematerialized()
step identifies the index as a materialized view index. -
Create a materialized view for an edge index. Edges indexes are vertex-centric
to a particular vertex label. For instance, the example below indexes anything
that a reviewer rates.
schema.vertexLabel('person').index('ratedByStars').outE('reviewed'). by('stars').ifNotExists().add()
Identify the vertex label and property keys for the index, in thevertexLabel()
andby()
steps, respectively. In theindex()
step, name the index. TheoutE()
step is used to define the direction of the edge.Note: For edge and property indexes, thematerialized()
step is not included, because all edge indexes are created as materialized views. -
Create an edge index that indexes both incoming and outgoing edges:
schema.vertexLabel('person').index('ratedByStars').bothE('reviewed'). by('stars').ifNotExists().add()
Identify the vertex label and property keys for the index, in the
vertexLabel()
andby()
steps, respectively. In theindex()
step, name the index. ThebothE()
step is used to define the direction of the edge. -
Create a materialized view for a property index:
schema.vertexLabel('person').index('byStartYear'). property('country').by('startYear').add()
Identify the vertex label for the index in thevertexLabel()
step. In theindex()
step, name the index. Theproperty()
andby()
steps identify the property key and its meta-property, respectively.Note: For edge and property indexes, thematerialized()
step is not included, because all edge indexes are created as materialized views.
-
Most commonly, a search index is created with multiple columns, chained
together as multiple
by()
steps in one statement:schema.vertexLabel('recipe').index('search').search().by('name').by('instructions').add()
Identify the vertex label and property keys for the index, in the
vertexLabel()
andby()
steps, respectively. In theindex()
step, name the indexsearch
; only this naming convention can be used. Thesearch()
step identifies the index as a search index. Since no option is specified, the property will be indexed both as Text and String.Tip: Only one search index can be created per vertex label.Textual search indexes are by default indexed in both tokenized (TextField) and non-tokenized (StrField) forms. This means that all textual predicates (token, tokenPrefix, tokenRegex, eq, neq, regex, prefix) will be usable with all textual vertex properties indexed. Practically, search indexes should be created using the
asString()
method only in cases where there is absolutely no use for tokenization and text analysis, such as for inventory categories (silverware, shoes, clothing). TheasText()
method is used if searching tokenized text, such as long multi-sentence descriptions. The query optimizer will choose whether to use analyzed or non-analyzed indexing based on the textual predicate used. -
Create a search index with only one property key indexed as Text():
schema.vertexLabel('recipe').index('search').search().by('instructions').asText().add()
-
A search index can specify the string indexing option along with the text
indexing option:
schema.vertexLabel('recipe').index('search').search().by('instructions').asString().by('name').asText().add()
This example specifically states how the search index will be constructed for each property.
-
Search indexes can also include non-text data types:
schema.vertexLabel('recipe').index('search').search().by('year').by('name').asString().add()
Data types other than text are inferred from the schema and DSE Search uses a comparable Solr data type. In this example,year
is indexed as an integer.CAUTION: TheDecimal
data type will index as aSolrDecimalStrField
. UseInt
,Long
,Float
, orDouble
to ensure that the Solr data types are used for sorting and range querying. -
Create a search index for geospatial data:
schema.propertyKey("coordinates").Point().single().create() schema.propertyKey("name").Text().single().create() schema.vertexLabel("place").properties("coordinates", "name").create() schema.vertexLabel("place").index("search").search().by("name").asText().by("coordinates").add()
In this example, the property coordinates is a point defining a longitude and latitude. The search index includes coordinates without a qualifying
asText()
orasString()
method. See Geospatial Schema for additional information. -
While DSE Graph natively supports geospatial searches, performing them without
a Search index does not scale as the number of vertices in the graph increases.
Doing such queries without a search index results in very inefficient query
performance because full scans are required. DSE Search indexes can index points
and linestrings, but not polygons.
//SEARCH INDEX ONLY WORKS FOR POINT AND LINESTRING schema.vertexLabel('location').index('search').search().by('point').add() schema.vertexLabel('lineLocation').index('search').search().by('line').add()
Without a search index, spatial queries always return exact results. DSE Search indexes, however, can trade off performance for accuracy.Note: A point of confusion can occur if the same geospatial query is run with or without a DSE Search index. Without a search index, geospatial queries always return exact results. DSE Search indexes, however, trade off write performance and index size for query accuracy with two tunable parameters,maxDistErr (default: 0.000009)
anddistErrPct (default: 0.025)
. Inconsistent results in these two cases are due to the distance calculation algorithm variation of the default values of these parameters. DSE Graph can pass values for these two parameters when creating the search index. ChangemaxDistErr
inwithError(maxDistErr, distErrPct)
to0.0
to force both index-backed and non-index-backed queries to yield the same value:schema.vertexLabel('location').index('search').search().by('point').withError(0.000009,0.0).add()
-
Create a search index for timestamp data:
schema. propertyKey('review_ts).Timestamp().create() schema.propertyKey('name').Text().create() schema.vertexLabel('rating').properties('name', 'review_ts').create() schema.vertexLabel('rating').index('search').search().by('name','review_ts').add()
-
Create a global index as a secondary index:
schema.vertexLabel('recipe').index('byRecipe').secondary().by('name').add()
Identify the vertex label and property key for the index, in the
vertexLabel()
andby()
steps, respectively. In theindex()
step, name the index. Thesecondary()
step identifies the index as a secondary index.
Example
// ********
// VERTEX INDEX
// ********
// SYNTAX:
// index('index_name').
// [secondary() | materialized() | search()].
// by('propertykey_name').
// [ asText() | asString() ].
// add()
// ********
schema.vertexLabel('person').index('byName').materialized().by('name').add()
schema.vertexLabel('meal_item').index('byName').materialized().by('name').add()
schema.vertexLabel('ingredient').index('byName').materialized().by('name').add()
//schema.vertexLabel('recipe').index('byCuisine').materialized().by('cuisine').add()
//schema.vertexLabel('book').index('byName').materialized().by('name').add()
schema.vertexLabel('meal').index('byType').secondary().by('type').add()
schema.vertexLabel('recipe').index('search').search().
by('instructions').by('name').by('cuisine').add()
schema.vertexLabel('book').index('search').search().
by('name').by('publishYear').add()
schema.vertexLabel('location').index('search').search().
by('geoPoint').withError(0.000009,0.0).add()
schema.vertexLabel('store').index('search').search().by('name').add()
schema.vertexLabel('home').index('search').search().by('name').add()
schema.vertexLabel('fridgeSensor').index('search').search().
by('cityId').by('sensorId').by('name').add()
// ********
// EDGE INDEX
// ********
// SYNTAX:
// index('index_name').
// [outE('edgeLabel') | inE('edgeLabel') ].
// by('propertykey_name').
// add()
// ********
schema.vertexLabel('recipe').index('byStars').inE('reviewed').
by('stars').ifNotExists().add()
schema.vertexLabel('person').index('ratedByStars').outE('reviewed').
by('stars').ifNotExists().add()
schema.vertexLabel('person').index('ratedByDate').outE('reviewed').
by('year').ifNotExists().add()
schema.vertexLabel('person').index('ratedByComments').outE('reviewed').
by('comment').ifNotExists().add()
schema.vertexLabel('recipe').index('byPersonOrRecipe').bothE('created').
by('createDate').ifNotExists().add()
// ********
// PROPERTY INDEX using meta-property 'livedIn'
// ********
// SYNTAX:
// index('index_name').
// property('propertykey_name').
// by('meta-propertykey_name').
// add()
// ********
schema.vertexLabel('person').index('byStartYear').
property('country').by('startYear').add()
schema.vertexLabel('person').index('byEndYear').
property('country').by('endYear').add()