Skip to main content

Cross-references

Overviewโ€‹

You can use cross-references to establish directional relationships between classes, for example from a Book to its Author, or from an Author to their Books.

To define a cross-reference, you must:

  1. At the class level, set up a cross-reference property in one class (from) referring to another (to) class, then
  2. For individual objects, establish the cross-reference between a particular object of the from class, to an object of the to class, using their ids.
Cross-references do not affect vectors

Creating cross-references does not affect object vectors in either direction.

Data setโ€‹

The example for this howto is a dataset consisting of 1000 questions & answers from the popular quiz show "Jeopardy!". The two classes of interest are: JeopardyQuestion and JeopardyCategory. Let's pick some objects of interest:

Questions:

{
"answer": "San Francisco",
"question": "This city's Cable Car Museum...",
"_additional": {
"id": "00ff6900-e64f-5d94-90db-c8cfa3fc851b"
}
}

Categories:

[
{
"title": "U.S. CITIES",
"_additional": {
"id": "20ffc68d-986b-5e71-a680-228dba18d7ef"
}
},
{
"title": "MUSEUMS",
"_additional": {
"id": "fec50326-dfa1-53c9-90e8-63d0240bd933"
}
}
]

Add a one-way cross-reference propertyโ€‹

This requires adding one reference property from a class referring to another, and adding one cross-reference per object pair.

To add a cross-reference property in the class definition, specify its dataType as the name of another class in the schema.

For example to specify the cross-reference from JeopardyQuestion to JeopardyCatgory:

    {
"class": "JeopardyQuestion",
"description": "A Jeopardy! question",
"properties": [
{"name": "question", "dataType": ["text"]},
{"name": "answer", "dataType": ["text"]},
{
"name": "hasCategory",
"dataType": ["JeopardyCategory"],
"description": "The category of the question",
},
],
},

To add a cross-reference from an object to another, specify its source class and id, the property name, and the class and id of the target object. In the example below, we'll add (not set) the "U.S. CITIES" category to the "San Francisco" Q&A (which by default only has the "MUSEUMS" category):

sf_id = "00ff6900-e64f-5d94-90db-c8cfa3fc851b"
us_cities_id = "20ffc68d-986b-5e71-a680-228dba18d7ef"

client.data_object.reference.add(
from_class_name="JeopardyQuestion",
from_uuid=sf_id,
from_property_name="hasCategory",
to_class_name="JeopardyCategory",
to_uuid=us_cities_id,
)

Add two-way cross-referencesโ€‹

This requires adding reference properties in both directions, and adding two cross-reference per object pair (from A -> to B and from B -> to A).

To define a bidirectional reference between two classes, add a property to each class with the dataType set to the name of the other class:

JeopardyQuestion class:

    {
"class": "JeopardyQuestion",
"description": "A Jeopardy! question",
"properties": [
{"name": "question", "dataType": ["text"]},
{"name": "answer", "dataType": ["text"]},
{
"name": "hasCategory",
"dataType": ["JeopardyCategory"],
"description": "The category of the question",
},
],
},

JeopardyCategory class:

    {
"class": "JeopardyCategory",
"description": "A Jeopardy! category",
"properties": [
{"name": "title", "dataType": ["text"]},
{
"name": "hasQuestion",
"dataType": ["JeopardyQuestion"],
"description": "Question in this category"
}
]
}

To set up a two-way cross-reference between two objects, set each cross-reference in turn:

sf_id = "00ff6900-e64f-5d94-90db-c8cfa3fc851b"
us_cities_id = "20ffc68d-986b-5e71-a680-228dba18d7ef"

# First, add the "hasQuestion" cross-reference property to the JeopardyCategory class
client.schema.property.create("JeopardyCategory", {
"name": "hasQuestion",
"dataType": ["JeopardyQuestion"]
})

# For the "San Francisco" JeopardyQuestion object, add a cross-reference to the "U.S. CITIES" JeopardyCategory object
client.data_object.reference.add(
from_class_name="JeopardyQuestion",
from_uuid=sf_id,
from_property_name="hasCategory",
to_class_name="JeopardyCategory",
to_uuid=us_cities_id,
)

# For the "U.S. CITIES" JeopardyCategory object, add a cross-reference to "San Francisco"
client.data_object.reference.add(
from_class_name="JeopardyCategory",
from_uuid=us_cities_id,
from_property_name="hasQuestion",
to_class_name="JeopardyQuestion",
to_uuid=sf_id,
)

Add multiple (one-to-many) cross-referencesโ€‹

To add a one-to-many cross-reference relationship, add to the source object each of the cross-references to the target objects that you need.

For example, to mark that the "San Francisco" Q&A belongs to multiple categories, e.g. "US. CITIES" and "MUSEUMS":

sf_id = "00ff6900-e64f-5d94-90db-c8cfa3fc851b"
us_cities_id = "20ffc68d-986b-5e71-a680-228dba18d7ef"
museums_id = "fec50326-dfa1-53c9-90e8-63d0240bd933"

# Add to "San Francisco" the "U.S. CITIES" category
client.data_object.reference.add(
from_class_name="JeopardyQuestion",
from_uuid=sf_id,
from_property_name="hasCategory",
to_class_name="JeopardyCategory",
to_uuid=us_cities_id,
)

# Add the "MUSEUMS" category as well
client.data_object.reference.add(
from_class_name="JeopardyQuestion",
from_uuid=sf_id,
from_property_name="hasCategory",
to_class_name="JeopardyCategory",
to_uuid=museums_id,
)

Delete a cross-referenceโ€‹

Deleting a cross-reference requires specifying the parameters that define the cross-reference.

To delete a cross-reference, specify the class, id and cross-reference property name of the source object, and the class and id of the target object:

sf_id = "00ff6900-e64f-5d94-90db-c8cfa3fc851b"
museums_id = "fec50326-dfa1-53c9-90e8-63d0240bd933"

# From the "San Francisco" JeopardyQuestion object, delete the "MUSEUMS" category cross-reference
# https://weaviate-python-client.readthedocs.io/en/stable/weaviate.data.references.html#weaviate.data.references.Reference.delete
sf = client.data_object.get(uuid=sf_id, class_name="JeopardyQuestion")
cat = client.data_object.get(uuid=museums_id, class_name="JeopardyCategory")

client.data_object.reference.delete(
from_class_name="JeopardyQuestion",
from_uuid=sf_id,
from_property_name="hasCategory",
to_class_name="JeopardyCategory",
to_uuid=museums_id,
)
tip

What happens if the to object is deleted? If an object is deleted, cross-references to it will be left intact. A Get query using the inline fragment syntax will correctly retrieve only fields in the existing cross-references objects, but getting the object by ID will show all cross-references, whether the objects they point to exist or not.

Update a cross-referenceโ€‹

To update the cross-references stored in a property of an object, specify the object's UUID, class name and cross-references property name, as well as the new list of cross-referenced UUIDs and their class (if all objects are of the same class) or classes (one class per each UUID):

sf_id = "00ff6900-e64f-5d94-90db-c8cfa3fc851b"
museums_id = "fec50326-dfa1-53c9-90e8-63d0240bd933"

# In the "San Francisco" JeopardyQuestion object, set the "hasCategory" cross-reference only to "MUSEUMS"
# https://weaviate-python-client.readthedocs.io/en/stable/weaviate.data.references.html#weaviate.data.references.Reference.update
client.data_object.reference.update(
from_class_name="JeopardyQuestion",
from_uuid=sf_id,
from_property_name="hasCategory",
to_class_names=["JeopardyCategory"],
to_uuids=[museums_id],
)

Batch creationโ€‹

Cross-references can be created using batches just like data objects. This can be done by using the same batch process, but by adding cross-references to the batch instead of data objects.

Please see the batch import how-to for more on batch imports.

Retrieve cross-referencesโ€‹

Cross-references in Weaviate are not themselves objects, but properties of objects. As such, you can retrieve cross-reference in one of two ways:

  1. Retrieve the object that it belongs to. This will return the cross-reference as a property of the object.
  2. Retrieve the cross-reference as a part of a query. Just as you can retrieve any other property of search results, you can retrieve cross-reference properties.

More Resourcesโ€‹

If you can't find the answer to your question here, please look at the:

  1. Frequently Asked Questions. Or,
  2. Knowledge base of old issues. Or,
  3. For questions: Stackoverflow. Or,
  4. For more involved discussion: Weaviate Community Forum. Or,
  5. We also have a Slack channel.