Filters

License badge Weaviate on Stackoverflow badge Weaviate issues on Github badge Weaviate v1.16.5 version badge Weaviate v1.16.5 version badge Weaviate total Docker pulls badge

Filters allow you to find specific data objects based on operators such as GreaterThan, LessThanEqual, Like, etc. You can mix filters with vector search parameters too. Also, you can use filters to sort or limit the number of returned objects.


Setting filters

Filters are added to GraphQL queries on the class level.

For example:

{
  Get {
    <Class> (
      <filter>: {
        variables: values
      }
    ){
      property
    }
  }
}

Where filter

Filter structure

Supported by the Get{} and Aggregate{} function.

The where filter is an algebraic object, which takes the following arguments:

  • Operator (which takes one of the following values)
    • And
    • Or
    • Not
    • Equal
    • NotEqual
    • GreaterThan
    • GreaterThanEqual
    • LessThan
    • LessThanEqual
    • Like
    • WithinGeoRange
    • IsNull
  • Operands: Is a list of Operator objects of this same structure, only used if the parent Operator is set to And or Or.
  • Path: Is a list of strings in Xpath style, indicating the property name of the class. If the property is a beacon (i.e., cross-reference), the path should be followed to the property of the beacon which should be specified as a list of strings. for a schema structure like:
    {
    "inPublication": {
      "Publication": {
        "name": "Wired"
      }
    }
    }
    

    the path selector for name will be ["inPublication", "Publication", "name"]

  • valueInt: The integer value where the Path’s last property name should be compared to.
  • valueBoolean: The boolean value that the Path’s last property name should be compared to.
  • valueString: The string value that the Path’s last property name should be compared to.
  • valueText: The text value that the Path’s last property name should be compared to.
  • valueNumber: The number (float) value that the Path’s last property name should be compared to.
  • valueDate: The date (ISO 8601 timestamp, formatted as RFC3339) value that the Path’s last property name should be compared to.
{
  Get {
    <Class>(where: {
        operator: <operator>,
        operands: [{
          path: [path],
          operator: <operator>
          <valueType>: <value>
        }, {
          path: [<matchPath>],
          operator: <operator>,
          <valueType>: <value>
        }]
      }) {
      <propertyWithBeacon> {
        <property>
        ... on <ClassOfWhereBeaconGoesTo> {
          <propertyOfClass>
        }
      }
    }
  }
}

Filter behavior of multi-word queries in Equal operator

The behavior for the Equal operator on multi-word string and text properties in where filters is as follows. Multi-word queries are broken up into single word segments. An object must contain all segments. How words are broken up depends on the datatype. For string properties only spaces defined word boundaries. For text properties all non-alphanumeric properties are considered word boundaries. E.g. for text: my email is alice@example.com is split into ["my", "email", "is", "alice" "example", "com"], whereas the same query string on a string property would be broken into ["my", "email", "is", "alice@example.com"].

Starting with v1.12.0 you can configure tokenization of string types to take the whole field into account instead of individual words.

Stopwords in text/string filter values

Starting with v1.12.0 you can configure your own stopword lists for the inverted index.

Single operand

You can create operator filters by setting the where key. You always need to include the GraphQL property path, the operator type, and the valueType plus a value.

For example, this filter selects articles from the class Article with a wordcount higher than 1000.

  {
  Get {
    Article(where: {
        path: ["wordCount"],    # Path to the property that should be used
        operator: GreaterThan,  # operator
        valueInt: 1000          # value (which is always = to the type of the path property)
      }) {
      title
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
  "path": ["wordCount"],
  "operator": "GreaterThan",
  "valueInt": 1000
}

query_result = (
  client.query
  .get("Article", "title")
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title')
      .withWhere({
        operator: 'GreaterThan',
        path: ['wordCount'],
        valueInt: 1000,
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	title := graphql.Field{Name: "title"}
	where := filters.Where().
		WithPath([]string{"wordCount"}).
		WithOperator(filters.GreaterThan).
		WithValueInt(1000)

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Article").
		WithFields(title).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field title = Field.builder().name("title").build();

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{ "wordCount" })
                .operator(Operator.GreaterThan)
                .valueInt(1000)
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Article")
                .withFields(title)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
  "query": "{
    Get {
      Article(where: {
          path: [\"wordCount\"],
          operator: GreaterThan,
          valueInt: 1000
        }) {
        title
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Example response

{
  "data": {
    "Get": {
      "Article": [
        {
          "title": "Opinion | John Lennon Told Them ‘Girls Don’t Play Guitar.’ He Was So Wrong."
        },
      ]
  },
  "errors": null
} 

Filter by id

You can filter object by their unique id or uuid, where you give the id as valueString.

  {
  Get {
    Article(where: {
        path: ["id"],
        operator: Equal,
        valueString: "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf"
      }) {
      title
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
  "path": ["id"],
  "operator": "Equal",
  "valueString": "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf"
}

query_result = (
  client.query
  .get("Article", "title")
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title')
      .withWhere({
        operator: 'Equal',
        path: ['id'],
        valueString: "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	title := graphql.Field{Name: "title"}
	where := filters.Where().
		WithPath([]string{"id"}).
		WithOperator(filters.Equal).
		WithValueString("e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf")

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Article").
		WithFields(title).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field title = Field.builder().name("title").build();

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{ "id" })
                .operator(Operator.Equal)
                .valueString("e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf")
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Article")
                .withFields(title)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
  "query": "{
    Get {
      Article(where: {
          path: [\"id\"],
          operator: Equal,
          valueString: \"e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf\"
        }) {
        title
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Example response

{
  "data": {
    "Get": {
      "Article": [
        {
          "title": "9 home improvement projects that are easier – and often cheaper – in the winter"
        },
      ]
  },
  "errors": null
} 

Filter by timestamps

Filtering can be performed with internal timestamps as well, such as creationTimeUnix and lastUpdateTimeUnix. These values can be represented either as Unix epoch milliseconds, or as RFC3339 formatted datetimes. Note that epoch milliseconds should be passed in as a valueString, and an RFC3339 datetime should be a valueDate.

Note: filtering by timestamp requires the target class to be configured to index timestamps. See here for details

  {
  Get {
    Article(where: {
        path: ["_creationTimeUnix"],
        operator: Greater,
        valueDate: "2022-03-18T20:29:19.063-0500" // can also use `valueString: "1647653359063"`
      }) {
      title
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
  "path": ["_creationTimeUnix"],
  "operator": "Greater",
  "valueDate": "2022-03-18T20:26:34.586-0500"
}

query_result = (
  client.query
  .get("Article", "title")
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title')
      .withWhere({
        operator: 'Greater',
        path: ['_creationTimeUnix'],
        valueDate: "2022-03-18T20:26:34.586-0500",
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"
	"time"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	title := graphql.Field{Name: "title"}
	where := filters.Where().
		WithPath([]string{"_creationTimeUnix"}).
		WithOperator(filters.LessThan).
		WithValueDate(time.Now())

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Article").
		WithFields(title).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field title = Field.builder().name("title").build();

        Date date;
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            date = df.parse("2022-03-18T20:26:34-0500");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{ "_creationTimeUnix" })
                .operator(Operator.GreaterThan)
                .valueDate(date)
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Article")
                .withFields(title)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
  "query": "{
    Get {
      Article(where: {
          path: [\"_creationTimeUnix\"],
          operator: Greater,
          valueDate: \"2022-03-18T20:26:34.586-0500\"
        }) {
        title
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Example Response

{
  "data": {
    "Get": {
      "Article": [
        {
          "title": "9 home improvement projects that are easier – and often cheaper – in the winter"
        },
      ]
  },
  "errors": null
} 

Filter by property length

Filtering can be performed with the length of properties.

The length of properties is calculated differently depending on the type:

  • array types: the number of entries in the array is used, where null (property not present) and empty arrays both have the length 0.
  • strings and texts: the number of characters, unicode characters such as 世 count as one character.
  • numbers, booleans, geo-coordinates, phone-numbers and data-blobs are not supported.
{
  Get {
    <Class>(where: {
        operator: <Operator>,
        valueInt: <value>
        path: [len(<property>)]
  }
}

Supported operators are (not) equal and greater/less than (equal) and values need to be 0 or larger.

Note: filtering by property length requires the target class to be configured to index the length. See here for details

Multiple operands

You can set multiple operands by providing an array.

For example, these filters select based on the class Article with a wordCount higher than 1000 and who are published before January 1st 2020. Note that you can filter a date and time just similar to numbers, with the valueDate given as string. Note that the valueDate should be formatted according to standard RFC3339.

  {
  Get {
    Article(where: {
      operator: And,
      operands: [{
          path: ["wordCount"],
          operator: GreaterThan,
          valueInt: 1000
        }, {
          path: ["publicationDate"],
          operator: LessThan,
          valueDate:"2020-01-01T00:00:00-07:00"
        }]
      }) {
      title
      wordCount
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
  "operator": "And",
  "operands": [{
        "path": ["wordCount"],
        "operator": "GreaterThan",
        "valueInt": 1000
      }, {
        path: ["publicationDate"],
        operator: LessThan,
        valueDate:"2020-01-01T00:00:00-07:00"
      }]
}

query_result = (
  client.query
  .get("Article", "title")
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title')
      .withWhere({
        operator: 'And',
        operands: [{
          path: ["wordCount"],
          operator: 'GreaterThan',
          valueInt: 1000
        }, {
          path: ["publicationDate"],
          operator: LessThan,
          valueDate:"2020-01-01T00:00:00-07:00"
        }]
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"
	"time"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	title := graphql.Field{Name: "title"}

	dateString := "2014-11-12T11:45:26.371Z"
	date, err := time.Parse(time.RFC3339, dateString)
	if err != nil {
		panic(err)
	}

	where := filters.Where().
		WithOperator(filters.And).
		WithOperands([]*filters.WhereBuilder{
			filters.Where().
				WithPath([]string{"wordCount"}).
				WithOperator(filters.GreaterThan).
				WithValueInt(1000),
			filters.Where().
				WithPath([]string{"publicationDate"}).
				WithOperator(filters.LessThan).
				WithValueDate(date),
		})

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Article").
		WithFields(title).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field title = Field.builder().name("title").build();

        WhereFilter wordCountGreaterThen = WhereFilter.builder()
                .path(new String[]{ "wordCount" })
                .operator(Operator.GreaterThan)
                .valueInt(1000)
                .build();

        Date date;
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            date = df.parse("2020-01-01T00:00:00-0700");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        WhereFilter wordCountLessThen = WhereFilter.builder()
                .path(new String[]{ "wordCount" })
                .operator(Operator.LessThan)
                .valueDate(date)
                .build();
        WhereFilter where = WhereFilter.builder()
                .operator(Operator.And)
                .operands(new WhereFilter[]{ wordCountGreaterThen, wordCountLessThen })
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Article")
                .withFields(title)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
    "query": "{
      Get {
        Article(where: {
          operator: And,
          operands: [{
              path: ["wordCount"],
              operator: GreaterThan,
              valueInt: 1000
            }, {
              path: ["publicationDate"],
              operator: LessThan,
              valueDate:"2020-01-01T00:00:00-07:00"
            }]
          }) {
          title
          wordCount
        }
      }
    }"
  }' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Like operator

Using the Like operator allows you to do string searches based on partial match. The capabilities of this operator are:

  • ? -> exactly one unknown character
    • car? matches cart, care, but not car
  • * -> zero, one or more unknown characters
    • car* matches car, care, carpet, etc
    • *car* matches car, healthcare, etc.
  {
  Get {
    Publication(where: {
          path: ["name"],
          operator: Like,
          valueString: "New *"
      }) {
      name
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
    "path": ["name"],
    "operator": "Like",
    "valueString": "New *"
}

query_result = (
  client.query
  .get("Publication", "name")
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Publication')
      .withFields('name')
      .withWhere({
        path: ["name"],
        operator: "Like",
        valueString: "New *"
    })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	name := graphql.Field{Name: "name"}
	where := filters.Where().
		WithPath([]string{"name"}).
		WithOperator(filters.Like).
		WithValueString("New *")

	ctx := context.Background()
	result, err := client.GraphQL().Get().
		WithClassName("Publication").
		WithFields(name).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field name = Field.builder().name("name").build();

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{ "name" })
                .operator(Operator.Like)
                .valueString("New *")
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Publication")
                .withFields(name)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{
  "query": "{
    Get {
      Publication(where: {
            path: [\"name\"],
            operator: Like,
            valueString: \"New *\"
        }) {
        name
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Notes

Each query using the Like operator iterates over the entire inverted index for that property. The search time will go up linearly with the dataset size. Be aware that there might be a point where this query is too expensive and will not work anymore. We will improve this implementation in a future release. You can leave feedback or feature requests in a Github issue.

Example response

{
  "data": {
    "Get": {
      "Publication": [
        {
          "name": "New Yorker"
        },
        {
          "name": "New York Times"
        }
      ]
    }
  },
  "errors": null
}

Beacon (reference) filters

You can also search for the value of the property of a beacon.

For example, these filters select based on the class Article but who have inPublication set to New Yorker.

  {
  Get {
    Article(where: {
        path: ["inPublication", "Publication", "name"],
        operator: Equal,
        valueString: "New Yorker"
      }) {
      title
      inPublication{
        ... on Publication{
          name
        }
      }
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
  'path': ["inPublication", "Publication", "name"],
  'operator': 'Equal',
  'valueString': "New Yorker"
}

query_result = (
  client.query
  .get('Article', ['title', 'inPublication{... on Publication{name}}'])
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title inPublication{... on Publication{name}}')
      .withWhere({
        path: ["inPublication", "Publication", "name"],
        operator: "Equal",
        valueString: "New Yorker"
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	fields := []graphql.Field{
		{Name: "title"},
		{Name: "inPublication", Fields: []graphql.Field{
			{Name: "... on Publication", Fields: []graphql.Field{
				{Name: "name"}},
			},
		}},
	}
	where := filters.Where().
		WithPath([]string{"inPublication", "Publication", "name"}).
		WithOperator(filters.Equal).
		WithValueString("New Yorker")

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Article").
		WithFields(fields...).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field title = Field.builder().name("title").build();
        Field inPublication = Field.builder()
                .name("inPublication")
                .fields(new Field[]{
                        Field.builder()
                                .name("... on Publication")
                                .fields(new Field[]{
                                        Field.builder().name("name").build()
                                })
                                .build()
                })
                .build();

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{ "inPublication", "Publication", "name" })
                .operator(Operator.Equal)
                .valueString("New Yorker")
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Article")
                .withFields(title, inPublication)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
    "query": "{
      Get {
        Article(where: {
            path: [\"inPublication\", \"Publication\", \"name\"],
            operator: Equal,
            valueString: \"New Yorker\"
          }) {
          title
          inPublication{
            ... on Publication{
              name
            }
          }
        }
      }
    }"
  }' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Filter objects by count of reference

Above example shows how filter by reference can solve straightforward questions like “Find all articles that are published by New Yorker”. But questions like “Find all articles that are written by authors that wrote at least two articles”, cannot be answered by the above query structure. It is however possible to filter by reference count. To do so, simply provide one of the existing compare operators (Equal, LessThan, LessThanEqual, GreaterThan, GreaterThanEqual) and use it directly on the reference element. For example:

  {
  Get {
    Author(
      where:{
        valueInt: 2,
        operator: GreaterThanEqual,
        path: ["WroteArticles"]
      }
    ) {
      name
      wroteArticles {
        ... on Article {
          title
        }
      }
    }
  }
 }
  import weaviate

client = weaviate.Client("http://localhost:8080")

where_filter = {
  'valueInt': 2,
  'operator': 'GreaterThanEqual',
  'path': ["WroteArticles"]
}

query_result = (
  client.query
  .get('Author', ['name', 'wroteArticles {... on Article {title}}'])
  .with_where(where_filter)
  .do()
)

print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Author')
      .withFields('name wroteArticles {... on Article {title}}')
      .withWhere({
        valueInt: 2,
        operator: "GreaterThanEqual",
        path: ["WroteArticles"]
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	fields := []graphql.Field{
		{Name: "name"},
		{Name: "wroteArticles", Fields: []graphql.Field{
			{Name: "... on Article", Fields: []graphql.Field{
				{Name: "title"},
			}},
		}},
	}

	where := filters.Where().
		WithPath([]string{"WroteArticles"}).
		WithOperator(filters.GreaterThanEqual).
		WithValueInt(2)

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Author").
		WithFields(fields...).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field name = Field.builder().name("name").build();
        Field wroteArticles = Field.builder()
                .name("wroteArticles")
                .fields(new Field[]{
                        Field.builder()
                                .name("... on Article")
                                .fields(new Field[]{
                                        Field.builder().name("title").build()
                                })
                                .build()
                })
                .build();

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{"WroteArticles"})
                .operator(Operator.GreaterThanEqual)
                .valueInt(2)
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Author")
                .withFields(name, wroteArticles)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
  "query": "{
    Get {
      Author(
        where:{
          valueInt: 2
          operator: GreaterThanEqual
          path: [\"WroteArticles\"]
        }
      ) {
        name
        wroteArticles {
          ... on Article {
            title
          }
        }
      }
    }
   }"
  }' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

GeoCoordinates filter

A special case of the Where filter is with geoCoordinates. This filter is only supported by the Get{} function. If you’ve set the geoCoordinates property type, you can search in an area based on kilometers.

For example, this curious returns all in a radius of 2KM around a specific geo-location:

  {
  Get {
    Publication(where: {
      operator: WithinGeoRange,
      valueGeoRange: {
        geoCoordinates: {
          latitude: 51.51,    # latitude
          longitude: -0.09    # longitude
        },
        distance: {
          max: 2000           # distance in meters
        }
      },
      path: ["headquartersGeoLocation"] # property needs to be of geoLocation type.
    }) {
      name
      headquartersGeoLocation {
        latitude
        longitude 
      }
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

get_articles_where = """
  {
    Get {
      Publication(where: {
        operator: WithinGeoRange,
        valueGeoRange: {
          geoCoordinates: {
            latitude: 51.51,    # latitude
            longitude: -0.09    # longitude
          },
          distance: {
            max: 2000           # distance in meters
          }
        },
        path: ["headquartersGeoLocation"] # property needs to be of geoLocation type.
      }) {
        name
        headquartersGeoLocation {
          latitude
          longitude 
        }
      }
    }
  }
"""

query_result = client.query.raw(get_articles_where)
print(query_result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Publication')
      .withFields('name headquartersGeoLocation{latitude longitude}')
      .withWhere({
        operator: "WithinGeoRange",
        path: ["headquartersGeoLocation"],
        valueGeoRange: {
          geoCoordinates: {
            latitude: 51.51,    
            longitude: -0.09    
          },
          distance: {
            max: 2000 
          }
        }
      })
      .do()
      .then(res => {
        console.log(JSON.stringify(res))
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	fields := []graphql.Field{
		{Name: "name"},
		{Name: "headquartersGeoLocation", Fields: []graphql.Field{
			{Name: "latitude"},
			{Name: "longitude"},
		}},
	}
	where := filters.Where().
		WithOperator(filters.WithinGeoRange).
		WithPath([]string{"headquartersGeoLocation"}).
		WithValueGeoRange(&filters.GeoCoordinatesParameter{
			Latitude:    51.51,
			Longitude:   -0.09,
			MaxDistance: 2000,
		})

	ctx := context.Background()

	result, err := client.GraphQL().Get().
		WithClassName("Publication").
		WithFields(fields...).
		WithWhere(where).
		Do(ctx)

	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
    public static void main(String[] args) {
        Config config = new Config("http", "localhost:8080");
        WeaviateClient client = new WeaviateClient(config);

        Field name = Field.builder().name("name").build();
        Field headquartersGeoLocation = Field.builder()
                .name("headquartersGeoLocation")
                .fields(new Field[]{
                        Field.builder().name("latitude").build(),
                        Field.builder().name("longitude").build()
                })
                .build();

        WhereFilter where = WhereFilter.builder()
                .path(new String[]{ "add" })
                .operator(Operator.WithinGeoRange)
                .valueGeoRange(WhereFilter.GeoRange.builder()
                        .geoCoordinates(WhereFilter.GeoCoordinates.builder()
                                .latitude(51.51f)
                                .longitude(-0.09f)
                                .build())
                        .distance(WhereFilter.GeoDistance.builder()
                                .max(2000f)
                                .build())
                        .build())
                .build();

        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName("Publication")
                .withFields(name, headquartersGeoLocation)
                .withWhere(where)
                .run();

        if (result.hasErrors()) {
            System.out.println(result.getError());
            return;
        }
        System.out.println(result.getResult());
    }
}
  $ echo '{ 
  "query": "{
    Get {
      Publication(where: {
        operator: WithinGeoRange,
        valueGeoRange: {
          geoCoordinates: {
            latitude: 51.51,
            longitude: -0.09
          },
          distance: {
            max: 2000
          }
        },
        path: [\"headquartersGeoLocation\"]
      }) {
        name
        headquartersGeoLocation {
          latitude
          longitude 
        }
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Example response

{
  "data": {
    "Get": {
      "Publication": [
        {
          "headquartersGeoLocation": {
            "latitude": 51.512737,
            "longitude": -0.0962234
          },
          "name": "Financial Times"
        },
        {
          "headquartersGeoLocation": {
            "latitude": 51.512737,
            "longitude": -0.0962234
          },
          "name": "International New York Times"
        }
      ]
    }
  },
  "errors": null
}

Filter by null state

Using the IsNull operator allows you to do filter for objects where given properties are null or not null. Note that zero-length arrays and empty strings are equivalent to a null value.

{
  Get {
    <Class>(where: {
        operator: IsNull,
        valueBoolean: <true/false>
        path: [<property>]
  }
}

Note: filtering by null-state requires the target class to be configured to index this. See here for details

Sorting

Note: Support for sorting was added in v1.13.0.

You can sort results by any primitive property, typically a text, string, number, or int property. When a query has a natural order (e.g. because of a near<Media> vector search), adding a sort operator will override the order.

Cost of Sorting / Architecture

Weaviate’s sorting implementation is built in a way that it does not lead to massive memory spikes; it does not need to load all objects to be sorted into memory completely. Only the property value being sorted is kept in memory.

As of now, Weaviate does not have any data structures on disk specific to sorting, such as a column-oriented storage mechanism. As a result when an object should be sorted, the whole object is identified on disk and the relevant property extracted. This works reasonably well for small scales (100s of thousand or millions), but comes with a high cost at large lists of objects to be sorted (100s of millions, billions). A column-oriented storage mechanism may be introduced in the future to overcome this performance limitation.

Sorting decisions

booleans order

false is considered smaller than true. false comes before true in ascending order and after true in descending order.

nulls order

null values are considered smaller than any non-null values. null values come first in ascending order and last in descending order.

arrays order

Arrays are compared by each element separately. Elements at the same position are compared to each other, starting from the beginning of an array. First element smaller than its counterpart makes whole array smaller.

Arrays are equal if they have the same size and all elements are equal. If array is subset of other array it is considered smaller.

Examples:

  • [1, 2, 3] = [1, 2, 3]
  • [1, 2, 4] < [1, 3, 4]
  • [2, 2] > [1, 2, 3, 4]
  • [1, 2, 3] < [1, 2, 3, 4]

Sorting API

  {
  Get {
    Article(sort: [{
      path: ["title"]     # Path to the property that should be used
      order: asc          # Sort order, possible values: asc, desc 
    }]) {
      title
      url
      wordCount
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

# one sorting configurations
result = (
  client.query
  .get("Article", ["title", "url", "wordCount"])
  .with_sort({ path: ["title"], order: "asc" })
  .do()
)
print(result)

# multiple sorting configurations
result = (
  client.query
  .get("Article", ["title", "url", "wordCount"])
  .with_sort([
    { path: ["title"], order: "asc" },
    { path: ["wordCount"], order: "desc" },
  ])
  .do()
)
print(result)

# or

result = (
  client.query
  .get("Article", ["title", "url", "wordCount"])
  .with_sort({ path: ["title"], order: "asc" })
  .with_sort({ path: ["wordCount"], order: "desc" })
  .do()
)
print(result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withSort([{ path: ["title"], order: "asc" }])
      .withFields('title url wordCount')
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
  "context"
  "fmt"

  "github.com/semi-technologies/weaviate-go-client/v4/weaviate"
  "github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
  cfg := weaviate.Config{
    Host:   "localhost:8080",
    Scheme: "http",
  }
  client := weaviate.New(cfg)

  title := graphql.Field{Name: "title"}
  url := graphql.Field{Name: "url"}
  wordCount := graphql.Field{Name: "wordCount"}

  byTitleAsc := graphql.Sort{
    Path: []string{"title"}, Order: graphql.Asc,
  }

  ctx := context.Background()
  result, err := client.GraphQL().Get().
    WithClassName("Article").
    WithSort(byTitleAsc).
    WithFields(title, url, wordCount).
    Do(ctx)
  if err != nil {
    panic(err)
  }
  fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.argument.SortArgument;
import technology.semi.weaviate.client.v1.graphql.query.argument.SortOrder;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
  public static void main(String[] args) {
    Config config = new Config("http", "localhost:8080");
    WeaviateClient client = new WeaviateClient(config);

    Field title = Field.builder().name("title").build();
    Field url = Field.builder().name("url").build();
    Field wordCount = Field.builder().name("wordCount").build();

    SortArgument byTitleAsc = client.graphQL().arguments().sortArgBuilder()
      .path(new String[]{ "title" })
      .order(SortOrder.asc)
      .build();

    Result<GraphQLResponse> result = client.graphQL().get()
      .withClassName("Article")
      .withSort(byTitleAsc)
      .withFields(title, url, wordCount)
      .run();
    if (result.hasErrors()) {
      System.out.println(result.getError());
      return;
    }
    System.out.println(result.getResult());
  }
}
  $ echo '{ 
  "query": "{
    Get {
      Article(sort: [{
        path: [\"title\"]
        order: asc
      }]) {
        title
        url
        wordCount
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Limit Argument

Supported by the Get{}, Explore{} and Aggregate{} function.

A limit argument limits the number of results.

An example of a stand-alone limit filter:

  {
  Get {
    Article(limit:5) {
      title
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

result = client.query.get("Article", ["title"]).with_limit(5).do()
print(result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title')
      .withLimit(5)
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
  "context"
  "fmt"

  "github.com/semi-technologies/weaviate-go-client/v4/weaviate"
  "github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
  cfg := weaviate.Config{
    Host:   "localhost:8080",
    Scheme: "http",
  }
  client := weaviate.New(cfg)

  title := graphql.Field{Name: "title"}

  ctx := context.Background()
  result, err := client.GraphQL().Get().
    WithClassName("Article").
    WithFields(title).
    WithLimit(5).
    Do(ctx)

  if err != nil {
    panic(err)
  }
  fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
  public static void main(String[] args) {
    Config config = new Config("http", "localhost:8080");
    WeaviateClient client = new WeaviateClient(config);

    Field title = Field.builder().name("title").build();

    Result<GraphQLResponse> result = client.graphQL().get()
      .withClassName("Article")
      .withFields(title)
      .withLimit(5)
      .run();

    if (result.hasErrors()) {
      System.out.println(result.getError());
      return;
    }
    System.out.println(result.getResult());
  }
}
  $ echo '{ 
  "query": "{
    Get {
      Article(limit:5) {
        title
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Example response

{
  "data": {
    "Get": {
      "Article": [
        {
          "title": "The War Vet, the Dating Site, and the Phone Call From Hell"
        },
        {
          "title": "Opinion | John Lennon Told Them ‘Girls Don’t Play Guitar.’ He Was So Wrong."
        },
        {
          "title": "The press pressed - Brazilian prosecutors go after Glenn Greenwald, an American journalist"
        },
        {
          "title": "Not to Ruin the Super Bowl, but the Sea Is Consuming Miami"
        },
        {
          "title": "Coca-Cola Resurrects Post of Chief Marketing Officer"
        }
      ]
    }
  },
  "errors": null
}

Offset argument (pagination)

Supported by the Get{}, Explore{} and Aggregate{} function.

The offset parameter works in conjunction with the existing limit parameter. For example, to list the first ten results, set limit: 10. Then, to “display the second page of 10”, set offset: 10, limit:10 and so on. E.g. to show the 9th page of 10 results, set offset:80, limit:10 to effectively display results 81-90.

An example of a stand-alone limit filter:

  {
  Get {
    Article(
      limit: 5,
      offset: 2
    ) {
      title
    }
  }
}
  import weaviate

client = weaviate.Client("http://localhost:8080")

result = (
  client.query
  .get("Article", "title")
  .with_limit(5)
  .with_offset(2)
  .do()
)

print(result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.graphql
      .get()
      .withClassName('Article')
      .withFields('title')
      .withLimit(5)
      .withOffset(2)
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      });
  package main

import (
  "context"
  "fmt"

  "github.com/semi-technologies/weaviate-go-client/v4/weaviate"
  "github.com/semi-technologies/weaviate-go-client/v4/weaviate/graphql"
)

func main() {
  cfg := weaviate.Config{
    Host:   "localhost:8080",
    Scheme: "http",
  }
  client := weaviate.New(cfg)

  title := graphql.Field{Name: "title"}

  ctx := context.Background()
  result, err := client.GraphQL().Get().
    WithClassName("Article").
    WithFields(title).
    WithLimit(5).
    WithOffset(5).
    Do(ctx)

  if err != nil {
    panic(err)
  }
  fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.graphql.model.GraphQLResponse;
import technology.semi.weaviate.client.v1.graphql.query.fields.Field;

public class App {
  public static void main(String[] args) {
    Config config = new Config("http", "localhost:8080");
    WeaviateClient client = new WeaviateClient(config);

    Field title = Field.builder().name("title").build();

    Result<GraphQLResponse> result = client.graphQL().get()
      .withClassName("Article")
      .withFields(title)
      .withLimit(5)
      .withOffset(5)
      .run();

    if (result.hasErrors()) {
      System.out.println(result.getError());
      return;
    }
    System.out.println(result.getResult());
  }
}
  $ echo '{ 
  "query": "{
    Get {
      Article(
        limit:5,
        offset: 2
        ) {
        title
      }
    }
  }"
}' | curl \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    http://localhost:8080/v1/graphql

🟢 Click here to try out this graphql example in the Weaviate Console.

Example response

{
  "data": {
    "Get": {
      "Article": [
        {
          "title": "Hong Kong tries its best to spoil China’s big anniversary"
        },
        {
          "title": "‘People don’t want any of them’: Peru election sees unpredictable contest"
        },
        {
          "title": "Brazil: homes of Bolsonaro associates raided in sweeping anti-corruption operation"
        },
        {
          "title": "If Convicting Trump Is Out of Reach, Managers Seek a Verdict From the Public and History"
        },
        {
          "title": "Watch The Juliana Plaintiffs Vic Barrett, Kelsey Juliana, and Levi Draheim in Conversation with Sandra Upson | Wired Video | CNE | Wired.com"
        }
      ]
    }
  }
}

Performance and Resource Considerations & Limitations

The pagination implementation is an offset-based implementation, not a cursor-based implementation. This has the following implications:

  • The cost of retrieving one further page is higher than that of the last. Effectively when searching for search results 91-100, Weaviate will internally retrieve 100 search results and discard results 0-90 before serving them to the user. This effect is amplified if running in a multi-shard setup, where each shard would retrieve 100 results, then the results aggregated and ultimately cut off. So in a 10-shard setup asking for results 91-100 Weavaite will effectively have to retrieve 1000 results (100 per shard) and discard 990 of them before serving. This means, high page numbers lead to longer response times and more load on the machine/cluster.
  • Due to the increasing cost of each page outlined above, there is a limit to how many objects can be retrieved using pagination. By default setting the sum of offset and limit to higher than 10,000 objects, will lead to an error. If you must retrieve more than 10,000 objects, you can increase this limit by setting the environment variable QUERY_MAXIMUM_RESULTS=<desired-value>. Warning: Setting this to arbitrarily high values can make the memory consumption of a single query explode and single queries can slow down the entire cluster. We recommend setting this value to the lowest possible value that does not interfere with your users’ expectations.
  • The pagination setup is not stateful. If the database state has changed between retrieving two pages there is no guarantee that your pages cover all results. If no writes happened, then pagination can be used to retrieve all possible within the maximum limit. This means asking for a single page of 10,000 objects will lead to the same results overall as asking for 100 pages of 100 results.

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 issues: Github. Or,
  5. Ask your question in the Slack channel: Slack.