Index tuple and UDT fields
This page provides guidelines for advanced data types, specifically tuples and user-defined types (UDTs).
Considerations
-
The tuple data type holds fixed-length sets of typed positional fields. Use a tuple as an alternative to a UDT.
-
A UDT facilitates handling multiple fields of related information in a table. UDTs are a specialization of tuples. All examples and documentation references to tuples apply to both tuples and UDTs.
Simplify applications that require multiple tables by using UDTs to represent the related fields of information, instead of storing the information in a separate table.
-
Tuples and UDTs are read and written as a single unit of information. Consider performance and memory impact when working with tuples and UDTs. Subfields are managed as the full tuple or UDT, and are not handled individually.
-
DSE Search does not support the following:
-
Tuples and UDTs that are used inside primary key declarations.
-
Tuples and UDTs that are used as CQL map values. Instead, use the workaround to simulate a map-like data model.
-
Dynamic fields as tuples or UDTs.
-
Tuple/UDT subfield sorting and faceting.
-
Usage
To add CQL tuple and user-defined type (UDT) columns to an existing search index, do the following:
-
Define a field for the table column using the DataStax Tuple class (
com.datastax.bdp.search.solr.core.types.TupleField). -
Define a field for each value in the CQL tuple or UDT column using the corresponding Solr field type.
The schema field name is
column_name.field<N>where the<column_name>matches the table column name and<N>is the field position starting at1.
Tuple configuration example
Use CQL commands to manage search indexes.
-
Add a tuple and index it.
Tuple columns are added as multiple fields:
ALTER TABLE solr.wiki ADD fieldname tuple<text,int>; ALTER SEARCH INDEX SCHEMA ON solr.wiki ADD fields.field <fieldname>;Adding the leading element
fields.inADD fields.field <fieldname>is optional and provides only cosmetic structure.The preceding example adds the following to the schema:
<field indexed="true" multiValued="false" name="fieldname" stored="true" type="TupleField" /> <field indexed="true" multiValued="false" name="fieldname.field1" stored="true" type="TextField" /> <field indexed="true" multiValued="false" name="fieldname.field2" stored="true" type="TrieIntField" /> -
Drop a tuple.
Drop the
TupleFieldand all of its child fields by dropping the base field name:ALTER SEARCH INDEX SCHEMA ON solr.wiki DROP field <fieldname>;Or, drop individual child fields:
ALTER SEARCH INDEX SCHEMA ON solr.wiki DROP field "<fieldname>.<field1>";
UDT configuration example
To create an index on a UDT, you must create the type, create a table that uses the type, and then alter the search index schema. This example demonstrates how to configure a UDT for DSE Search using CQL commands.
-
In the search schema, declare the
UDTFieldclass:<fieldType class="com.datastax.bdp.search.solr.core.types.UDTField" name="UDTField"/> -
Create the UDT:
CREATE TYPE Address (street text, city text) -
Create a table with a UDT column:
CREATE TABLE Location ( id text primary key, address frozen<Address> ); -
Configure the
UDTFieldin the search index schema:<field name="address" type="UDTField" indexed="true" stored="true"/> <field name="address.street" type="text" indexed="true" stored="true"/> <field name="address.city" type="text" indexed="true" stored="true"/>
Nested tuples and UDTs
DSE Search supports queries for nested tuples and UDTs. For example, you can nest and declare tuples and UDTs inside CQL lists and sets. You cannot nest tuples and UDTS inside maps or keys.
-
Create an
Addresstype with a nested tuple for the residents of a given address:CREATE TYPE Address (street text, city text, residents set<tuple<text, text>>) -
Create a table with the
Addresstype:CREATE TABLE Location (id text, address Address) -
In the search schema, declare the
TupleFieldand the nestedTupleField:<field name="address" type="UDTField" indexed="true" stored="true"/> <field name="address.street" type="text" indexed="true" stored="true"/> <field name="address.city" type="text" indexed="true" stored="true"/> <field name="address.residents" type="TupleField" indexed="true" stored="true" multiValued="true"/> <field name="address.residents.field1" type="text" indexed="true" stored="true"/> <field name="address.residents.field2" type="text" indexed="true" stored="true"/>The
residentsnested tuple isTupleField. Each nested field is concatenated with each parent tuple or UDT by using periods.
Tuples and UDTs as CQL map values
DSE Search does not support using tuples and UDTs as CQL map values. Use this workaround to simulate a map-like data model:
-
Declare a collection of tuples or UDTs that have a type field that represents what would have been the map key:
Create the tuple type. The tuple type applies to tuples and UDTs.
CREATE TYPE Address (type text, street text, city text)Create table for UDT:
CREATE TABLE Person (name text primary key, addresses set<frozen<address>>)Or create a table for a tuple:
CREATE TABLE Person (name text primary key, addresses set<frozen<tuple<text, text, text>>>) -
Using this collection of tuples or UDTs as a map-like data model, it is possible to query for person addresses of a given type (key).
For example, to query for persons whose home address is in London:
{!tuple}addresses.type:Home AND addresses.city:London