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.
Multi-tenancy

For classes where multi-tenancy is enabled, you can establish a cross-reference from a multi-tenancy class object to:

  • A non-multi-tenancy class object, or
  • A multi-tenancy class object belonging to the same tenant.

See Manage data: multi-tenancy operations for details on how.

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 JeopardyCategory:

import weaviate.classes as wvc

client.collections.create(
name="JeopardyQuestion",
description="A Jeopardy! question",
properties=[
wvc.Property(name="question", data_type=wvc.DataType.TEXT),
wvc.Property(name="answer", data_type=wvc.DataType.TEXT),
wvc.ReferenceProperty(
name="hasCategory",
target_collection="JeopardyCategory"
)
]
)

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):

import weaviate.classes as wvc

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

questions = client.collections.get("JeopardyQuestion")
questions.data.reference_add(
from_uuid=sf_id,
from_property="hasCategory",
ref=wvc.Reference.to(uuids=us_cities_id)
)

Add two-way cross-references

This requires adding reference properties in both directions, and adding two cross-references 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:

JeopardyCategory collection:

import weaviate.classes as wvc

category = client.collections.create(
name="JeopardyCategory",
description="A Jeopardy! category",
properties=[
wvc.Property(name="title", data_type=wvc.DataType.TEXT)
]
)

JeopardyQuestion collection:

client.collections.create(
name="JeopardyQuestion",
description="A Jeopardy! question",
properties=[
wvc.Property(name="question", data_type=wvc.DataType.TEXT),
wvc.Property(name="answer", data_type=wvc.DataType.TEXT),
wvc.ReferenceProperty(
name="hasCategory",
target_collection="JeopardyCategory"
)
]
)

Update JeopardyCategory to add the reference to JeopardyQuestion:

# Add the reference to JeopardyQuestion, after it was created
category.config.add_property(
wvc.ReferenceProperty(
name="hasQuestion",
target_collection="JeopardyQuestion"
)
)

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

import weaviate.classes as wvc

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

# For the "San Francisco" JeopardyQuestion object, add a cross-reference to the "U.S. CITIES" JeopardyCategory object
questions = client.collections.get("JeopardyQuestion")
questions.data.reference_add(
from_uuid=sf_id,
from_property="hasCategory",
ref=wvc.Reference.to(us_cities_id)
)

# For the "U.S. CITIES" JeopardyCategory object, add a cross-reference to "San Francisco"
categories = client.collections.get("JeopardyCategory")
categories.data.reference_add(
from_uuid=us_cities_id,
from_property="hasQuestion",
ref=wvc.Reference.to(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":

import weaviate.classes as wvc

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

questions = client.collections.get("JeopardyQuestion")
questions.data.reference_add(
from_uuid=sf_id,
from_property="hasCategory",
ref=wvc.Reference.to([us_cities_id, museums_id]) # add multiple references
)

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:

import weaviate.classes as wvc

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
questions = client.collections.get("JeopardyQuestion")
questions.data.reference_delete(
from_uuid=sf_id,
from_property="hasCategory",
ref=wvc.Reference.to(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):

import weaviate.classes as wvc

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"
questions = client.collections.get("JeopardyQuestion")
questions.data.reference_replace(
from_uuid=sf_id,
from_property="hasCategory",
ref=wvc.Reference.to(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.