Filters let you include, or exclude, particular objects from your result set based on provided conditions.

For a list of filter operators, see the [API reference page](../apis/graphql-filters.md#filter-structure).

## Filter with one condition

Add a `filter` to your query, to limit the result set.

:::code-group{sync="languages"}
```python title="Python" {5}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    filters=Filter.by_property("round").equal("Double Jeopardy!"),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go" {4-7}
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "question"}, graphql.Field{Name: "answer"}, graphql.Field{Name: "round"}).
  WithWhere(filters.Where().
    WithPath([]string{"round"}).
    WithOperator(filters.Equal).
    WithValueString("Double Jeopardy!")).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");
var response = jeopardy.query.fetchObjects(q -> q
    .filters(Filter.property("round").eq("Double Jeopardy!"))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {3}
var jeopardy = client.Collections.Use("JeopardyQuestion");
var response = await jeopardy.Query.FetchObjects(
    filters: Filter.Property("round").IsEqual("Double Jeopardy!"),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```

```graphql title="GraphQL" {5-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["round"],
        operator: Equal,
        valueText: "Double Jeopardy!"
      }
    ) {
      question
      answer
      round
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "garage",
          "question": "This French word originally meant \"a place where one docks\" a boat, not a car",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "Mexico",
          "question": "The Colorado River provides much of the border between this country's Baja California Norte & Sonora",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "Amy Carter",
          "question": "On September 1, 1996 this former first daughter married Jim Wentzel at the Pond House near Plains",
          "round": "Double Jeopardy!"
        }
      ]
    }
  }
}
```
:::

## Filter with multiple conditions

To filter with two or more conditions, use `And`, `Or` and `Not` to define the relationship between the conditions.

::::tabs{sync="languages"}
:::tab{title="Python"}
The `v4` Python client API provides filtering by `any_of`, or `all_of`, as well as using `&` or `|` operators.

- Use `any_of` or `all_of` for filtering by any, or all of a list of provided filters.

- Use `&` or `|` for filtering by pairs of provided filters.

#### Filter with `&` or `|`

```python {5-11}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    # Use & as AND
    #     | as OR
    filters=(
        Filter.by_property("round").equal("Double Jeopardy!") &
        Filter.by_property("points").less_than(600) &
        Filter.not_(Filter.by_property("answer").equal("Yucatan"))
    ),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

#### Filter with `any of`

```python {5-11}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    filters=(
        Filter.any_of([  # Combines the below with `|`
            Filter.by_property("points").greater_or_equal(700),
            Filter.by_property("points").less_than(500),
            Filter.by_property("round").equal("Double Jeopardy!"),
        ])
    ),
    limit=5
)

for o in response.objects:
    print(o.properties)
```

#### Filter with `all of`

```python {5-11}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    filters=(
        Filter.all_of([  # Combines the below with `&`
            Filter.by_property("points").greater_than(300),
            Filter.by_property("points").less_than(700),
            Filter.by_property("round").equal("Double Jeopardy!"),
        ])
    ),
    limit=5
)

for o in response.objects:
    print(o.properties)
```
:::

:::tab{title="JavaScript/TypeScript"}
Use `Filters.and` and `Filters.or` methods to combine filters in the JS/TS `v3` API. `Filters.not` is used to negate a filter using the logical NOT operator.

These methods take variadic arguments (e.g. `Filters.and(f1, f2, f3, ...)`). To pass an array (e.g. `fs`) as an argument, provide it like so: `Filters.and(...fs)` which will spread the array into its elements.

```typescript
import weaviate, { Filters } from 'weaviate-client';
```
:::

:::tab{title="Go"}
```go {9-21}
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(
    graphql.Field{Name: "question"},
    graphql.Field{Name: "answer"},
    graphql.Field{Name: "round"},
    graphql.Field{Name: "points"},
  ).
  WithWhere(filters.Where().
    WithOperator(filters.And).
    WithOperands([]*filters.WhereBuilder{
      filters.Where().WithPath([]string{"round"}).WithOperator(filters.Equal).WithValueString("Double Jeopardy!"),
      filters.Where().WithPath([]string{"points"}).WithOperator(filters.LessThan).WithValueInt(600),
      // Add a NOT operator to exclude a specific answer
      filters.Where().
        WithOperator(filters.Not).
        WithOperands([]*filters.WhereBuilder{
          filters.Where().WithPath([]string{"answer"}).WithOperator(filters.Equal).WithValueString("Yucatan"),
        }),
    }),
  ).
  WithLimit(3).
  Do(ctx)
```
:::

:::tab{title="Java"}
```java {4-7}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");
var response = jeopardy.query.fetchObjects(q -> q
    // Combine filters with Filter.and(), Filter.or(), and Filter.not()
    .filters(Filter.and(Filter.property("round").eq("Double Jeopardy!"),
        Filter.property("points").lt(600),
        Filter.not(Filter.property("answer").eq("Yucatan"))))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```
:::

:::tab{title="C#"}
```csharp {3-8}
var jeopardy = client.Collections.Use("JeopardyQuestion");
var response = await jeopardy.Query.FetchObjects(
    // Combine filters with Filter.And(), Filter.Or(), and Filter.Not()
    filters: Filter.AllOf(
        Filter.Property("round").IsEqual("Double Jeopardy!"),
        Filter.Property("points").IsLessThan(600),
        Filter.Not(Filter.Property("answer").IsEqual("Yucatan"))
    ),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```
:::

:::tab{title="GraphQL"}
```graphql {5-20}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        operator: And,
        operands: [
          {
            path: ["round"],
            operator: Equal,
            valueText: "Double Jeopardy!",
          },
          {
            path: ["points"],
            operator: LessThan,
            valueInt: 600,
          },
        ]

      }
    ) {
      question
      answer
      round
      points
    }
  }
}
```
:::
::::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "Mexico",
          "points": 200,
          "question": "The Colorado River provides much of the border between this country's Baja California Norte & Sonora",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "Amy Carter",
          "points": 200,
          "question": "On September 1, 1996 this former first daughter married Jim Wentzel at the Pond House near Plains",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "Greek",
          "points": 400,
          "question": "Athenians speak the Attic dialect of this language",
          "round": "Double Jeopardy!"
        }
      ]
    }
  }
}
```
:::

## Combine filters with `And` or `Or`

Group and nest filter conditions with `And` and `Or` operators to express compound logic.

:::code-group{sync="languages"}
```python title="Python" {5-6}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    filters=Filter.by_property("answer").like("*bird*") &
            (Filter.by_property("points").greater_than(700) | Filter.by_property("points").less_than(300)),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
import weaviate, { Filters } from 'weaviate-client';
```

```go title="Go" {9-11}
operands := []*filters.WhereBuilder{
  filters.Where().WithPath([]string{"points"}).WithOperator(filters.GreaterThan).WithValueInt(300),
  filters.Where().WithPath([]string{"points"}).WithOperator(filters.LessThan).WithValueInt(700),
}

response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "question"}, graphql.Field{Name: "answer"}, graphql.Field{Name: "round"}, graphql.Field{Name: "points"}).
  WithWhere(filters.Where().
    WithOperator(filters.And).
    WithOperands(operands)).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4-6}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");
var response = jeopardy.query.fetchObjects(q -> q
    .filters(Filter.and(Filter.property("answer").like("*bird*"),
        Filter.or(Filter.property("points").gt(700),
            Filter.property("points").lt(300))))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {3-9}
var jeopardy = client.Collections.Use("JeopardyQuestion");
var response = await jeopardy.Query.FetchObjects(
    filters: Filter.AllOf(
        Filter.Property("answer").IsLike("*bird*"),
        Filter.AnyOf(
            Filter.Property("points").IsGreaterThan(700),
            Filter.Property("points").IsLessThan(300)
        )
    ),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```

```graphql title="GraphQL" {5-30}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        operator: And,
        operands: [
          {
            path: ["answer"],
            operator: Like,
            valueText: "*bird*",
          },
          {
            operator: Or,
            operands: [
                {
                    path: ["points"],
                    operator: GreaterThan,
                    valueInt: 700,
                },
                {
                    path: ["points"],
                    operator: LessThan,
                    valueInt: 300,
                },
            ]
          }
        ]

      }
    ) {
      question
      answer
      round
      points
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "The Firebird",
          "points": 1000,
          "question": "This title character has the face & arms of a woman & a body of feathers that tapers off in flames",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "the Firebird",
          "points": 800,
          "question": "This Stravinsky character first played by Tamara Karsavina has the face & arms of a girl & a body of feathers",
          "round": "Double Jeopardy!"
        }
      ]
    }
  }
}
```
:::

:::accordion{title="Additional information"}
To create a nested filter, follow these steps.

- Set the outer `operator` equal to `And` or `Or`.
- Add `operands`.
- Inside an `operand` expression, set `operator` equal to `And` or `Or` to add the nested group.
- Add `operands` to the nested group as needed.
:::

## Combine filters and search operators

Filters work with search operators like `nearXXX`, `hybrid`, and `bm25`.

:::code-group{sync="languages"}
```python title="Python" {6}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.near_text(
    query="fashion icons",
    filters=Filter.by_property("points").greater_than(200),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go" {4-9}
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "question"}, graphql.Field{Name: "answer"}, graphql.Field{Name: "round"}, graphql.Field{Name: "points"}).
  WithWhere(filters.Where().
    WithPath([]string{"points"}).
    WithOperator(filters.GreaterThan).
    WithValueInt(200)).
  WithNearText(client.GraphQL().NearTextArgBuilder().
    WithConcepts([]string{"fashion icons"})).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");
var response = jeopardy.query.nearText("fashion icons", q -> q
    .filters(Filter.property("points").gt(200))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {4}
var jeopardy = client.Collections.Use("JeopardyQuestion");
var response = await jeopardy.Query.NearText(
    "fashion icons",
    filters: Filter.Property("points").IsGreaterThan(200),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```

```graphql title="GraphQL" {5-12}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["points"],
        operator: GreaterThan,
        valueInt: 200
      }
      nearText: {
        concepts: ["fashion icons"]
    }
    ) {
      question
      answer
      round
      points
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "fashion designers",
          "points": 400,
          "question": "Ted Lapidus, Guy Laroche, Christian Lacroix",
          "round": "Jeopardy!"
        },
        {
          "answer": "Dapper Flapper",
          "points": 400,
          "question": "A stylish young woman of the 1920s",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "Women's Wear Daily",
          "points": 800,
          "question": "This daily chronicler of the fashion industry launched \"W\", a bi-weekly, in 1972",
          "round": "Jeopardy!"
        }
      ]
    }
  }
}
```
:::

## `ContainsAny` Filter

The `ContainsAny` operator works on text properties and take an array of values as input. It will match objects where the property **contains any (i.e. one or more)** of the values in the array.

:::code-group{sync="languages"}
```python title="Python" {5,7-8}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")

token_list = ["australia", "india"]
response = jeopardy.query.fetch_objects(
    # Find objects where the `answer` property contains any of the strings in `token_list`
    filters=Filter.by_property("answer").contains_any(token_list),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go" {1,6-9}
tokenList := []string{"australia", "india"}

response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "question"}, graphql.Field{Name: "answer"}, graphql.Field{Name: "round"}, graphql.Field{Name: "points"}).
  WithWhere(filters.Where().
    WithPath([]string{"answer"}).
    WithOperator(filters.ContainsAny).
    WithValueText(tokenList...)).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4,6-7}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");

String[] tokens = new String[] {"australia", "india"};
var response = jeopardy.query.fetchObjects(q -> q
    // Find objects where the `answer` property contains any of the strings in `token_list`
    .filters(Filter.property("answer").containsAny(tokens))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {3,6-7}
var jeopardy = client.Collections.Use("JeopardyQuestion");

string[] tokens = ["australia", "india"];

var response = await jeopardy.Query.FetchObjects(
    // Find objects where the `answer` property contains any of the strings in `tokens`
    filters: Filter.Property("answer").ContainsAny(tokens),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```

```graphql title="GraphQL" {5-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["answer"],
        operator: ContainsAny,
        valueText: ["australia", "india"]
      }
    ) {
      question
      answer
      round
      points
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "India",
          "points": 100,
          "question": "Country that is home to Parsis & Sikhs",
          "round": "Jeopardy!"
        },
        {
          "answer": "Australia",
          "points": 400,
          "question": "The redundant-sounding Townsville, in this country's Queensland state, was named for Robert Towns",
          "round": "Double Jeopardy!"
        },
        {
          "answer": "Australia",
          "points": 100,
          "question": "Broken Hill, this country's largest company, took its name from a small town in New South Wales",
          "round": "Jeopardy!"
        }
      ]
    }
  }
}
```
:::

## `ContainsAll` Filter

The `ContainsAll` operator works on text properties and take an array of values as input. It will match objects where the property **contains all** of the values in the array.

:::code-group{sync="languages"}
```python title="Python" {5,8-9}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")

token_list = ["blue", "red"]

response = jeopardy.query.fetch_objects(
    # Find objects where the `question` property contains all of the strings in `token_list`
    filters=Filter.by_property("question").contains_all(token_list),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go" {1,6-9}
tokenList := []string{"blue", "red"}

response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "question"}, graphql.Field{Name: "answer"}, graphql.Field{Name: "round"}, graphql.Field{Name: "points"}).
  WithWhere(filters.Where().
    WithPath([]string{"question"}).
    WithOperator(filters.ContainsAll).
    WithValueText(tokenList...)).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4-5,8-9}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");

String[] tokens = new String[] {"blue", "red"};


var response = jeopardy.query.fetchObjects(q -> q
    // Find objects where the `question` property contains all of the strings in `tokens`
    .filters(Filter.property("question").containsAll(tokens))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {3,6-7}
var jeopardy = client.Collections.Use("JeopardyQuestion");

string[] tokens = ["blue", "red"];

var response = await jeopardy.Query.FetchObjects(
    // Find objects where the `question` property contains all of the strings in `tokens`
    filters: Filter.Property("question").ContainsAll(tokens),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```

```graphql title="GraphQL" {5-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["question"],
        operator: ContainsAll,
        valueText: ["blue", "red"]
      }
    ) {
      question
      answer
      round
      points
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "James Patterson",
          "points": 1000,
          "question": "His Alex Cross thrillers include \"Roses are Red\" & \"Violets are Blue\"",
          "round": "Jeopardy!"
        },
        {
          "answer": "a chevron",
          "points": 800,
          "question": "Chevron's red & blue logo is this heraldic shape, meant to convey rank & service",
          "round": "Jeopardy!"
        },
        {
          "answer": "litmus",
          "points": 400,
          "question": "Vegetable dye that turns red in acid solutions & blue in alkaline solutions",
          "round": "Double Jeopardy!"
        }
      ]
    }
  }
}
```
:::

## `ContainsNone` Filter

The `ContainsNone` operator works on text properties and take an array of values as input. It will match objects where the property **contains none** of the values in the array.

:::code-group{sync="languages"}
```python title="Python" {5,8-9}
from weaviate.classes.query import Filter

jeopardy = client.collections.get("JeopardyQuestion")

token_list = ["bird", "animal"]

response = jeopardy.query.fetch_objects(
    # Find objects where the `question` property contains none of the strings in `token_list`
    filters=Filter.by_property("question").contains_none(token_list),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
import weaviate, { Filters } from 'weaviate-client';
```

```go title="Go" {1,15-18}
tokenList := []string{"bird", "animal"}

response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(
    graphql.Field{Name: "question"},
    graphql.Field{Name: "answer"},
    graphql.Field{
      Name: "hasCategory",
      Fields: []graphql.Field{
        {Name: "... on JeopardyCategory", Fields: []graphql.Field{{Name: "title"}}},
      },
    },
  ).
  WithWhere(filters.Where().
    WithPath([]string{"answer"}).
    WithOperator(filters.ContainsNone).
    WithValueText(tokenList...)).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4,7-8}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");

String[] tokens = new String[] {"bird", "animal"};

var response = jeopardy.query.fetchObjects(q -> q
    // Find objects where the `question` property contains none of the strings in `token_list`
    .filters(Filter.property("question").containsNone(tokens))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {3,6-7}
var jeopardy = client.Collections.Use("JeopardyQuestion");

string[] tokens = ["bird", "animal"];

var response = await jeopardy.Query.FetchObjects(
    // Find objects where the `question` property contains none of the strings in `tokens`
    filters: Filter.Property("question").ContainsNone(tokens),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "Frank Lloyd Wright",
          "hasCategory": [
            {
              "title": "PEOPLE"
            }
          ],
          "question": "In 1939 this famous architect polished off his Johnson Wax Building in Racine, Wisconsin"
        },
        {
          "answer": "a luffa",
          "hasCategory": [
            {
              "title": "FOOD"
            }
          ],
          "question": "When it's young & tender, this gourd used in the bathtub can be eaten like a squash"
        },
        {
          "answer": "a snail",
          "hasCategory": [
            {
              "title": "SCIENCE & NATURE"
            }
          ],
          "question": "Like an escargot, the abalone is an edible one of these gastropods"
        }
      ]
    }
  }
}
```
:::

## `ContainsAny`, `ContainsAll` and `ContainsNone` with batch delete

If you want to do a batch delete, see [Delete objects](../how-to-manage-objects/delete.md#containsany--containsall--containsnone).

## Filter text on partial matches

If the object property is a `text`, or `text`-like data type such as object ID, use `Like` to filter on partial text matches.

:::code-group{sync="languages"}
```python title="Python" {5}
from weaviate.classes.query import Filter

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    filters=Filter.by_property("answer").like("*ala*"),
    limit=3
)

for o in response.objects:
    print(o.properties)
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go" {4-7}
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "question"}, graphql.Field{Name: "answer"}, graphql.Field{Name: "round"}).
  WithWhere(filters.Where().
    WithPath([]string{"answer"}).
    WithOperator(filters.Like).
    WithValueText("*inter*")).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4}
CollectionHandle<Map<String, Object>> jeopardy =
    client.collections.use("JeopardyQuestion");
var response = jeopardy.query.fetchObjects(q -> q
    .filters(Filter.property("answer").like("*ala*"))
    .limit(3));

for (var o : response.objects()) {
  System.out.println(o.properties());
}
```

```csharp title="C#" {3}
var jeopardy = client.Collections.Use("JeopardyQuestion");
var response = await jeopardy.Query.FetchObjects(
    filters: Filter.Property("answer").IsLike("*ala*"),
    limit: 3
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties));
}
```

```graphql title="GraphQL" {5-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["answer"],
        operator: Like,
        valueText: "*inter*"
      }
    ) {
      question
      answer
      round
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "interglacial",
          "question": "This term refers to the warm periods within ice ages; we're in one of those periods now",
          "round": "Jeopardy!"
        },
        {
          "answer": "the Interior",
          "question": "In 1849, Thomas Ewing, \"The Logician of the West\", became the USA's first Secy. of this Cabinet Dept.",
          "round": "Jeopardy!"
        },
        {
          "answer": "Interlaken, Switzerland",
          "question": "You can view the Jungfrau Peak from the main street of this town between the Brienz & Thun Lakes",
          "round": "Final Jeopardy!"
        }
      ]
    }
  }
}
```
:::

:::accordion{title="Additional information"}
The `*` wildcard operator matches zero or more characters. The `?` operator matches exactly one character.

Currently, the `Like` filter is not able to match wildcard characters (`?` and `*`) as literal characters ([read more](../apis/graphql-filters.md#wildcard-literal-matches-with-like)).
:::

## Filter using cross-references

:::callout{intent="warning" title="Cross-references and query performance"}
Queries involving cross-references can be slower than queries that do not involve cross-references, especially at scale such as for multiple objects or complex queries.

At the first instance, we strongly encourage you to consider whether you can avoid using cross-references in your data schema. As a scalable AI database, Weaviate is well-placed to perform complex queries with vector, keyword and hybrid searches involving filters. You may benefit from rethinking your data schema to avoid cross-references where possible.

For example, instead of creating separate "Author" and "Book" collections with cross-references, consider embedding author information directly in Book objects and using searches and filters to find books by author characteristics.
:::

To filter on properties from a cross-referenced object, add the collection name to the filter.

:::code-group{sync="languages"}
```python title="Python" {5-6}
from weaviate.classes.query import Filter, QueryReference

jeopardy = client.collections.use("JeopardyQuestion")
response = jeopardy.query.fetch_objects(
    filters=Filter.by_ref(link_on="hasCategory").by_property("title").like("*Sport*"),
    return_references=QueryReference(link_on="hasCategory", return_properties=["title"]),
    limit=3
)

for o in response.objects:
    print(o.properties)
    print(o.references["hasCategory"].objects[0].properties["title"])
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go" {14-17}
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(
    graphql.Field{Name: "question"},
    graphql.Field{Name: "answer"},
    graphql.Field{Name: "round"},
    graphql.Field{
      Name: "hasCategory",
      Fields: []graphql.Field{
        {Name: "... on JeopardyCategory", Fields: []graphql.Field{{Name: "title"}}},
      },
    },
  ).
  WithWhere(filters.Where().
    WithPath([]string{"hasCategory", "JeopardyCategory", "title"}).
    WithOperator(filters.Like).
    WithValueText("*Sport*")).
  WithLimit(3).
  Do(ctx)
```

```java title="Java"
// Coming soon
```

```csharp title="C#"
```

```graphql title="GraphQL" {5-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["hasCategory", "JeopardyCategory", "title"],
        operator: Like,
        valueText: "*Sport*"
      }
    ) {
      question
      answer
      round
      hasCategory {... on JeopardyCategory { title } }
    }
  }
}
```
:::

:::accordion{title="Example response"}
The output is like this:

```json
{
  "data": {
    "Get": {
      "JeopardyQuestion": [
        {
          "answer": "Sampan",
          "hasCategory": [
            {
              "title": "TRANSPORTATION"
            }
          ],
          "question": "Smaller than a junk, this Oriental boat usually has a cabin with a roof made of mats",
          "round": "Jeopardy!"
        },
        {
          "answer": "Emmitt Smith",
          "hasCategory": [
            {
              "title": "SPORTS"
            }
          ],
          "question": "In 1994 this Dallas Cowboy scored 22 touchdowns; in 1995 he topped that with 25",
          "round": "Jeopardy!"
        },
        {
          "answer": "Lee Iacocca",
          "hasCategory": [
            {
              "title": "TRANSPORTATION"
            }
          ],
          "question": "Chrysler executive who developed the Ford Mustang",
          "round": "Jeopardy!"
        }
      ]
    }
  }
}
```
:::

## By geo-coordinates

:::callout{intent="note" title="Limitations"}
Currently, geo-coordinate filtering is limited to the nearest 800 results from the source location, which will be further reduced by any other filter conditions and search parameters.

If you plan on a densely populated dataset, consider using another strategy such as geo-hashing into a `text` datatype, and filtering further, such as with a `ContainsAny` filter.
:::

:::code-group{sync="languages"}
```python title="Python"
from weaviate.classes.query import Filter
from weaviate.classes.query import GeoCoordinate

response = publications.query.fetch_objects(
    filters=(
        Filter
        .by_property("headquartersGeoLocation")
        .within_geo_range(
            coordinate=GeoCoordinate(
                latitude=52.39,
                longitude=4.84
            ),
            distance=1000  # In meters
        )
    )
)

for o in response.objects:
    print(o.properties)  # Inspect returned objects
```

```typescript title="JavaScript/TypeScript" {4-8}
const publications = client.collections.use('Publication');

const geoResult = await publications.query.fetchObjects({
  filters: publications.filter.byProperty('headquartersGeoLocation').withinGeoRange({
    latitude: 52.39,
    longitude: 4.84,
    distance: 1000
  }),
})

console.log(JSON.stringify(geoResult.objects, null, 2));
```

```go title="Go"
geoFilter := filters.Where().
  WithPath([]string{"headquartersGeoLocation"}).
  WithOperator(filters.WithinGeoRange).
  WithValueGeoRange(&filters.GeoCoordinatesParameter{
    Latitude:    52.39,
    Longitude:   4.84,
    MaxDistance: 1000,
  })

response, err := client.GraphQL().Get().
  WithClassName("Publication").
  WithWhere(geoFilter).
  WithFields(graphql.Field{Name: "name"}).
  WithFields(graphql.Field{
    Name: "headquartersGeoLocation",
    Fields: []graphql.Field{
      {Name: "latitude"},
      {Name: "longitude"},
    },
  }).
  Do(ctx)
```

```java title="Java"
var response = publications.query.fetchObjects(
    q -> q.filters(Filter.property("headquartersGeoLocation")
        .withinGeoRange(52.39f, 4.84f, 1000.0f) // In meters
    ));

for (var o : response.objects()) {
  System.out.println(o.properties()); // Inspect returned objects
}
```

```csharp title="C#"
var response = await publications.Query.FetchObjects(
    filters: Filter
        .Property("headquartersGeoLocation")
        .IsWithinGeoRange(new GeoCoordinate(52.39f, 4.84f), 1000.0f) // In meters
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties)); // Inspect returned objects
}
```

```graphql title="GraphQL"
{
  Get {
    Publication(where: {
      operator: WithinGeoRange,
      valueGeoRange: {
        geoCoordinates: {
          latitude: 52.3932696,    # latitude
          longitude: 4.8374263     # longitude
        },
        distance: {
          max: 1000           # distance in meters
        }
      },
      path: ["headquartersGeoLocation"]  # property needs to be a geoLocation data type.
    }) {
      name
      headquartersGeoLocation {
        latitude
        longitude
      }
    }
  }
}
```
:::

## By `DATE` datatype

To filter by a `DATE` datatype property, specify the date/time as an [RFC 3339](https://datatracker.ietf.org/doc/rfc3339/) timestamp, or a client library-compatible type such as a Python `datetime` object.

:::code-group{sync="languages"}
```python title="Python" {4-7,11-12}
from datetime import datetime, timezone
from weaviate.classes.query import Filter, MetadataQuery

# Set the timezone for avoidance of doubt
filter_time = datetime(2022, 6, 10).replace(tzinfo=timezone.utc)
# The filter threshold could also be an RFC 3339 timestamp, e.g.:
# filter_time = "2022-06-10T00:00:00.00Z"

response = collection.query.fetch_objects(
    limit=3,
    # This property (`some_date`) is a `DATE` datatype
    filters=Filter.by_property("some_date").greater_than(filter_time),
)

for o in response.objects:
    print(o.properties)  # Inspect returned objects
```

```typescript title="JavaScript/TypeScript" {7}
const filterTime = new Date(2020, 5, 10)  // Note that the month is 0-indexed
// The filter threshold could also be an RFC 3339 timestamp, e.g.:
// filterTime = '2022-06-10T00:00:00.00Z'

result = await collectionWithDate.query.fetchObjects({
  limit: 3,
  filters: jeopardy.filter.byProperty('some_date').greaterThan(filterTime),
})

result.objects.forEach((object) =>
  console.log(JSON.stringify(object.properties, null, 2))
);
```

```go title="Go"
// Note: In Go, months are 1-indexed
filterTime := time.Date(2020, 6, 10, 0, 0, 0, 0, time.UTC)
// Alternatively, you can use an RFC 3339 timestamp:
// filterTime, _ := time.Parse(time.RFC3339, "2022-06-10T00:00:00Z")

response, err := client.GraphQL().Get().
  WithClassName("Article").
  WithLimit(3).
  WithFields(graphql.Field{Name: "publicationDate"}).
  WithWhere(filters.Where().
    WithPath([]string{"publicationDate"}).
    WithOperator(filters.GreaterThan).
    WithValueDate(filterTime)).
  Do(ctx)
```

```java title="Java" {1-3,6-7}
// Set the timezone for avoidance of doubt - use string format for filter
String filterTime = "2022-06-10T00:00:00Z";
// The filter threshold must be an RFC 3339 timestamp string

var response = collection.query.fetchObjects(q -> q.limit(3)
    // This property (`some_date`) is a `DATE` datatype
    .filters(Filter.property("some_date").gt(filterTime))
);

for (var o : response.objects()) {
  System.out.println(o.properties()); // Inspect returned objects
}
```

```csharp title="C#" {1-2,6-7}
// Use DateTime object for filter
DateTime filterTime = new DateTime(2022, 6, 10, 0, 0, 0, DateTimeKind.Utc);

var response = await collection.Query.FetchObjects(
    limit: 3,
    // This property (`some_date`) is a `DATE` datatype
    filters: Filter.Property("some_date").IsGreaterThan(filterTime)
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties)); // Inspect returned objects
}
```
:::

## Filter by metadata

Filters also work with metadata properties such as object id, property length, and timestamp.

For the full list, see [API references: Filters](../apis/graphql-filters.md#special-cases).

### By object `id`

:::code-group{sync="languages"}
```python title="Python"
from weaviate.classes.query import Filter

collection = client.collections.use("Article")

target_id = "00037775-1432-35e5-bc59-443baaef7d80"
response = collection.query.fetch_objects(
    filters=Filter.by_id().equal(target_id)
)

for o in response.objects:
    print(o.properties)  # Inspect returned objects
    print(o.uuid)
```

```typescript title="JavaScript/TypeScript"
const myArticleCollection = client.collections.use('Article');
```

```go title="Go"
targetID := "00037775-1432-35e5-bc59-443baaef7d80"
response, err := client.GraphQL().Get().
  WithClassName("Article").
  WithFields(graphql.Field{Name: "title"}).
  WithWhere(filters.Where().
    WithPath([]string{"id"}).
    WithOperator(filters.Equal).
    WithValueString(targetID)).
  WithFields(
    graphql.Field{Name: "title"},
    graphql.Field{
      Name: "_additional",
      Fields: []graphql.Field{
        {Name: "id"},
      },
    },
  ).
  Do(ctx)
```

```java title="Java"
CollectionHandle<Map<String, Object>> collection =
    client.collections.use("Article");

String targetId = "00037775-1432-35e5-bc59-443baaef7d80";
var response = collection.query
    .fetchObjects(q -> q.filters(Filter.uuid().eq(targetId)));

for (var o : response.objects()) {
  System.out.println(o.properties()); // Inspect returned objects
  System.out.println(o.uuid());
}
```

```csharp title="C#"
var collection = client.Collections.Use("Article");

Guid targetId = Guid.Parse("00037775-1432-35e5-bc59-443baaef7d80");

var response = await collection.Query.FetchObjects(filters: Filter.UUID.IsEqual(targetId));

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties)); // Inspect returned objects
    Console.WriteLine(o.UUID);
}
```

```graphql title="GraphQL" {4-8}
{
  Get {
    Article(
      where: {
        path: ["id"],
        operator: Equal,
        valueText: "00037775-1432-35e5-bc59-443baaef7d80"
      }
    ) {
      title
      _additional { id }
    }
  }
}
```
:::

### By object timestamp

This filter requires the [property timestamp](../reference-configuration/indexing-inverted-index.md#indextimestamps) to [be indexed](../how-to-manage-collections/inverted-index.md#set-inverted-index-parameters).

:::code-group{sync="languages"}
```python title="Python" {6-7,11-12}
from datetime import datetime, timezone
from weaviate.classes.query import Filter, MetadataQuery

collection = client.collections.use("Article")

# Set the timezone for avoidance of doubt (otherwise the client will emit a warning)
filter_time = datetime(2020, 1, 1).replace(tzinfo=timezone.utc)

response = collection.query.fetch_objects(
    limit=3,
    filters=Filter.by_creation_time().greater_than(filter_time),
    return_metadata=MetadataQuery(creation_time=True)
)

for o in response.objects:
    print(o.properties)  # Inspect returned objects
    print(o.metadata.creation_time)  # Inspect object creation time
```

```typescript title="JavaScript/TypeScript"
const myArticleCollection = client.collections.use('Article');
```

```go title="Go"
timestampStr := "2020-01-01T00:00:00+00:00"
layout := "2006-01-02T15:04:05Z07:00"

timestamp, err := time.Parse(layout, timestampStr)
if err != nil {
  fmt.Println("Error parsing time:", err)
  return
}

response, err := client.GraphQL().Get().
  WithClassName("Article").
  WithFields(graphql.Field{Name: "title"}).
  WithWhere(filters.Where().
    WithPath([]string{"_creationTimeUnix"}).
    WithOperator(filters.GreaterThan).
    WithValueDate(timestamp)).
  WithFields(
    graphql.Field{Name: "title"},
    graphql.Field{
      Name: "_additional",
      Fields: []graphql.Field{
        {Name: "creationTimeUnix"},
      },
    },
  ).
  WithLimit(3).
  Do(ctx)
```

```java title="Java"
//   // highlight-start
//   // Set the timezone for avoidance of doubt
//   OffsetDateTime filterTime =
//       OffsetDateTime.of(2020, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
//   // highlight-end

//   CollectionHandle<Map<String, Object>> collection =
//       client.collections.use("Article");
//   var response = collection.query.fetchObjects(q -> q.limit(3)
//       // highlight-start
//       .filters(Filter.byCreationTime().gt(filterTime.toInstant()))
//       .returnMetadata(Metadata.CREATION_TIME_UNIX)
//   // highlight-end
//   );

//   for (var o : response.objects()) {
//     System.out.println(o.properties()); // Inspect returned objects
//     System.out.println(o.metadata().creationTimeUnix()); // Inspect object creation time
//   }
```

```csharp title="C#" {1-2,8-9}
// Set the timezone for avoidance of doubt
DateTime filterTime = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc);

var collection = client.Collections.Use("Article");

var response = await collection.Query.FetchObjects(
    limit: 3,
    filters: Filter.CreationTime.IsGreaterThan(filterTime),
    returnMetadata: MetadataOptions.CreationTime
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties)); // Inspect returned objects
    Console.WriteLine(o.Metadata.CreationTime); // Inspect object creation time
}
```

```graphql title="GraphQL" {4-9}
{
  Get {
    Article(
      limit: 3
      where: {
        path: ["_creationTimeUnix"],
        operator: GreaterThan,
        valueDate: "2020-01-01T00:00:00+00:00"
      }
    ) {
      title
      _additional { creationTimeUnix }
    }
  }
}
```
:::

### By object property length

This filter requires the [property length](../reference-configuration/indexing-inverted-index.md#indexpropertylength) to [be indexed](../how-to-manage-collections/inverted-index.md#set-inverted-index-parameters).

:::code-group{sync="languages"}
```python title="Python" {7}
from weaviate.classes.query import Filter

collection = client.collections.use("JeopardyQuestion")

response = collection.query.fetch_objects(
    limit=3,
    filters=Filter.by_property("answer", length=True).greater_than(length_threshold),
)

for o in response.objects:
    print(o.properties)  # Inspect returned objects
    print(len(o.properties["answer"]))  # Inspect property length
```

```typescript title="JavaScript/TypeScript"
const jeopardy = client.collections.use('JeopardyQuestion');
```

```go title="Go"
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "answer"}).
  WithWhere(filters.Where().
    WithPath([]string{"len(answer)"}).
    WithOperator(filters.GreaterThan).
    WithValueInt(20)).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {6}
int lengthThreshold = 20;

CollectionHandle<Map<String, Object>> collection =
    client.collections.use("JeopardyQuestion");
var response = collection.query.fetchObjects(q -> q.limit(3)
    .filters(Filter.propertyLen("answer").gt(lengthThreshold))
);

for (var o : response.objects()) {
  System.out.println(o.properties()); // Inspect returned objects
  System.out.println(((String) o.properties().get("answer")).length()); // Inspect property length
}
```

```csharp title="C#" {6}
int lengthThreshold = 20;

var collection = client.Collections.Use("JeopardyQuestion");
var response = await collection.Query.FetchObjects(
    limit: 3,
    filters: Filter.Property("answer").HasLength().IsGreaterThan(lengthThreshold)
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties)); // Inspect returned objects
    Console.WriteLine(o.Properties["answer"].ToString().Length); // Inspect property length
}
```

```graphql title="GraphQL" {4-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["len(answer)"],
        operator: GreaterThan,
        valueInt: 20
      }
    ) {
      answer
    }
  }
}
```
:::

### By object null state

This filter requires the [property null state](../reference-configuration/indexing-inverted-index.md#indexnullstate) to [be indexed](../how-to-manage-collections/inverted-index.md#set-inverted-index-parameters).

:::code-group{sync="languages"}
```python title="Python" {7-8}
from weaviate.classes.query import Filter

collection = client.collections.use("WineReview")

response = collection.query.fetch_objects(
    limit=3,
    # This requires the `country` property to be configured with `index_null_state=True``
    filters=Filter.by_property("country").is_none(True)  # Find objects where the `country` property is null
)
for o in response.objects:
    print(o.properties)  # Inspect returned objects
```

```typescript title="JavaScript/TypeScript" {2-3}
const result = await jeopardy.query.fetchObjects({
  // This requires the `points` property to be configured with `index_null_state=True``
  filters: jeopardy.filter.byProperty('points').isNull(true),
  limit: 3
})

for (let object of result.objects) {
  console.log(JSON.stringify(object.properties, null, 2));
}
```

```go title="Go"
response, err := client.GraphQL().Get().
  WithClassName("JeopardyQuestion").
  WithFields(graphql.Field{Name: "points"}).
  WithWhere(filters.Where().
    WithPath([]string{"points"}).
    WithOperator(filters.IsNull).
    WithValueBoolean(true)).
  WithLimit(3).
  Do(ctx)
```

```java title="Java" {4-5}
CollectionHandle<Map<String, Object>> collection =
    client.collections.use("WineReview");
var response = collection.query.fetchObjects(q -> q.limit(3)
    // This requires the `country` property to be configured with`index_null_state=True``
    .filters(Filter.property("country").isNull()) // Find objects where the `country` property is null
);

for (var o : response.objects()) {
  System.out.println(o.properties()); // Inspect returned objects
}
```

```csharp title="C#" {4-5}
var collection = client.Collections.Use("WineReview");
var response = await collection.Query.FetchObjects(
    limit: 3,
    // This requires the `country` property to be configured with `indexNullState: true` in the schema
    filters: Filter.Property("country").IsNull() // Find objects where the `country` property is null
);

foreach (var o in response.Objects)
{
    Console.WriteLine(JsonSerializer.Serialize(o.Properties)); // Inspect returned objects
}
```

```graphql title="GraphQL" {4-9}
{
  Get {
    JeopardyQuestion(
      limit: 3
      where: {
        path: ["points"],
        operator: IsNull,
        valueBoolean: true
      }
    ) {
      points
    }
  }
}
```
:::

## Filter on nested object properties

:::callout{intent="warning" title="Preview feature"}
Available from Weaviate `v1.38` as a preview, gated by the `WEAVIATE_PREVIEW_NESTED_FILTERING=on` environment variable on the server. The path syntax and operator semantics are stable, but the on-disk encoding may change before GA. Don't rely on persistent state from preview clusters carrying over to the GA release. The env var is removed at GA and the feature is enabled unconditionally.
:::

[`object` and `object[]` properties](../reference-configuration/datatypes.md#object) carry their own nested schemas. To filter on a value inside a nested object, use a single dotted path naming the path from the parent property down to the leaf you want to compare.

Given a collection like this:

```python
client.collections.create(
    name="Document",
    vector_config=Configure.Vectors.self_provided(),
    inverted_index_config=Configure.inverted_index(index_null_state=True),
    properties=[
        Property(name="title", data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
        Property(
            name="cars",
            data_type=DataType.OBJECT_ARRAY,
            nested_properties=[
                Property(name="make",  data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
                Property(name="color", data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
                Property(
                    name="tires",
                    data_type=DataType.OBJECT_ARRAY,
                    nested_properties=[
                        Property(name="brand", data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
                        Property(name="width", data_type=DataType.INT),
                    ],
                ),
            ],
        ),
    ],
)
```

The filter property is a single dotted path. The dot is the only separator. An optional `[N]` after any segment pins that segment to an array index (0-based).

| Path                     | Meaning                                                                  |
| ------------------------ | ------------------------------------------------------------------------ |
| `cars.make`              | Any car's `make` (matches if **any** element of the `cars` array has it) |
| `cars[0].make`           | The first car's `make` (positional)                                      |
| `cars.tires.width`       | Any tire on any car (recursive across two `object[]` levels)             |
| `cars[1].tires[2].brand` | The second car's third tire's `brand` (positional through nesting)       |

`[N]` on a segment requires that segment to be an `object[]` (array). Every intermediate segment must be `object` or `object[]`. You cannot pivot through a scalar. The leaf may be any supported scalar type.

### Match any element (default)

A path without `[N]` markers matches if **any** element in the parent array satisfies the condition.

:::code-group{sync="languages"}
```python title="Python" {3}
# "any car has make = Toyota" — matches Doc 1 (first car) and Doc 2 (only car)
response = docs.query.fetch_objects(
    filters=Filter.by_property("cars.make").equal("Toyota"),
    return_properties=["title"],
)

for o in response.objects:
    print(o.properties)
```
:::

### Match by position

Use `[N]` to pin a path segment to a specific array index. Indices are 0-based.

:::code-group{sync="languages"}
```python title="Python" {3}
# "the FIRST car has make = Toyota" — Doc 3's first car is Honda, so it's excluded
response = docs.query.fetch_objects(
    filters=Filter.by_property("cars[0].make").equal("Toyota"),
    return_properties=["title"],
)
```
:::

### Same-element correlation across leaves

Combining two leaf filters with `And` matches when **the same element** in the parent array satisfies both. A document with one car `(Toyota, blue)` and another `(Honda, red)` would not match `cars.make = "Toyota" AND cars.color = "red"`. Both conditions must hold on the **same** car.

:::code-group{sync="languages"}
```python title="Python" {5-8}
# "the SAME car is both Toyota AND red" — only Doc 1's first car qualifies.
# Without same-element correlation a doc with separate (Toyota, blue) and
# (Honda, red) cars would also match, which is wrong.
response = docs.query.fetch_objects(
    filters=(
        Filter.by_property("cars.make").equal("Toyota")
        & Filter.by_property("cars.color").equal("red")
    ),
    return_properties=["title"],
)
```
:::

### Deep / recursive paths

`object[]` can nest inside `object[]` to any depth. Each segment in the dotted path traverses one level.

:::code-group{sync="languages"}
```python title="Python" {3}
# "any tire on any car is wider than 200" — Doc 1 (215) and Doc 3 (250)
response = docs.query.fetch_objects(
    filters=Filter.by_property("cars.tires.width").greater_than(200),
    return_properties=["title"],
)
```
:::

### Check whether a nested object is absent

Pointing a path at an `object` or `object[]` segment (rather than a scalar leaf) is only valid with `IsNull`, which asks whether that whole sub-object is present.

:::code-group{sync="languages"}
```python title="Python" {3}
# "the first car has no tires" — only the Toyota in Doc 2
response = docs.query.fetch_objects(
    filters=Filter.by_property("cars[0].tires").is_none(True),
    return_properties=["title"],
)
```
:::

### Limitations

:::callout{intent="note"}
- **Allowed leaf data types**: `text`, `int`, `number`, `boolean`, `date`, `uuid`, and their array variants. `blob`, `blobHash`, `geoCoordinates`, `phoneNumber`, and cross-references (`cref`) are not allowed inside nested objects for nested filtering.
- **`IndexFilterable` is required**: nested filtering uses the filterable inverted index on each leaf. `IndexRangeFilters` and `IndexSearchable` flags exist on nested-property definitions but are not yet exercised by the nested searcher. Range filters on nested numeric leaves currently use the filterable bucket.
- **Tokenization matters**: nested `text` leaves use the same tokenization options as flat properties. For exact-match filters on names, codes, or identifiers, set `tokenization: field` on the leaf so the value is stored as a single token.
- **Reference-path vs nested-path**: a reference-path filter is a multi-element `Path` (`["inCity", "City", "name"]`) traversing cross-references; a nested-path filter is a **single-element** path with dots inside it (`["cars.make"]`).
:::

## Filter considerations

### Tokenization

Weaviate converts filter terms into tokens. The default tokenization is `word`. The `word` tokenizer keeps alphanumeric characters, lowercase them and splits on whitespace. It converts a string like "Test\_domain\_weaviate" into "test", "domain", and "weaviate".

For details and additional tokenization methods, see [Tokenization](../reference-configuration/collections.md#tokenization).

### Improve filter performance

If you encounter slow filter performance, consider adding a `limit` parameter or additional `where` operators to restrict the size of your data set.

## List of filter operators

For a list of filter operators, see [the reference page](../apis/graphql-filters.md#filter-structure).

## Related pages

- [Connect to Weaviate](../connect-to-weaviate/index.md)
- [API References: Filters](../apis/graphql-filters.md)

## Questions and feedback

Have a question or feedback? Here's how to reach us.

::::card-grid
:::card{title="Community Forum" href="https://forum.weaviate.io/c/support" icon="messages-square"}
Ask questions and connect with other developers on our **Community forum**.
:::

:::card{title="Support" href="/guides/support-overview" icon="life-buoy"}
Weaviate Cloud user or customer? Find the right channel on the **Support page**.
:::
::::

## Related pages

- [Agents](./agents-index.md)
- [AI-assisted Weaviate code generation](./ai-assisted-vibe-coding-index.md)
- [APIs](./apis-index.md)
- [Authorization and authentication](./authorization-and-authentication-index.md)
- [Benchmarks](./benchmarks-index.md)
- [Best practices](./best-practices-index.md)
- [Client libraries](./clients-index.md)
- [Client Libraries / SDKs](./client-libraries-index.md)
- [Cloud](./cloud-index.md)
- [Cloud account management](./cloud-account-management-index.md)

# Agent Instructions

This portal answers questions programmatically. To receive a synthesized,
source-cited answer instead of crawling page by page, append the `?ask=`
query parameter to any page URL on this site:

    /guides/quickstart?ask=how+do+I+authenticate

Optional parameters:

- `&goal=<what-you-are-trying-to-do>` steers the answer toward your
  objective (e.g. `&goal=write+a+python+client`).
- `&version=<label>` scopes the answer to a mounted version when the
  portal publishes more than one.

The response is `text/markdown`: the answer followed by a `# Sources` list
of the portal pages it was grounded in. Status codes are the contract:

- `200` — the answer; `402` — the portal owner’s plan or answer credits are
  exhausted (surface this to your operator; do NOT retry); `429` — you are
  rate-limited; back off for the `Retry-After` seconds; `503` — the answer
  lane is temporarily unavailable; fall back to crawling the `.md` pages.

For the full corpus map read `llms.txt` at the site root; for the tool
surface (search + page fetch as MCP tools) see `/mcp`.
