Skip to main content

Filter by Field Presence

Find documents that CONTAIN a field​

Dynamic query​

  • Use WhereExists to return documents that contain the specified field.
    Documents that are missing the field are excluded from the results.

  • RavenDB uses an auto-index to process the filter, creating one if needed.
    Learn more about this query type in Query a collection - with filtering.

  • You can check field presence using either a field name or a nested field path, as shown below.


Filter documents by field name​

The following query returns employees whose documents contain the FirstName field:

List<Employee> employees = session.Advanced
.DocumentQuery<Employee>()
.WhereExists("FirstName")
// Or use a lambda expression: .WhereExists(e => e.FirstName)
.ToList();

Filter documents by nested field path​

You can also check for a nested field by specifying its full path.
The following query returns employees whose documents contain Latitude at Address.Location.Latitude:

List<Employee> employees = session.Advanced
.DocumentQuery<Employee>()
.WhereExists("Address.Location.Latitude")
// Or use a lambda expression:
// .WhereExists(e => e.Address.Location.Latitude)
.ToList();

Static index query​

  • When querying a static index, use the index-field name in WhereExists.
    The index must include the field whose presence you want to check.

  • The following index maps:

    • FirstName to an index-field with the same name.

    • Address.Location.Latitude to an index-field named Latitude.

    • The document ID to an index-field named Id, to retain entries for documents with missing fields.
      See Static index query for missing fields for details.

      public class Employees_ByFieldPresence
      : AbstractIndexCreationTask<Employee, Employees_ByFieldPresence.IndexEntry>
      {
      public class IndexEntry
      {
      // The index-fields
      public string Id { get; set; }
      public string FirstName { get; set; }
      public double Latitude { get; set; }
      }

      public Employees_ByFieldPresence()
      {
      Map = employees => from employee in employees
      select new IndexEntry
      {
      // Include Id so documents with missing fields still have an index entry.
      Id = employee.Id,

      FirstName = employee.FirstName,
      Latitude = employee.Address.Location.Latitude
      };
      }
      }

Filter documents by field name​

The following example queries the Employees_ByFieldPresence index and returns employee documents that contain the FirstName field:

List<Employee> employees = session.Advanced
.DocumentQuery<Employee, Employees_ByFieldPresence>()
.WhereExists("FirstName")
// Or use a lambda expression: .WhereExists(e => e.FirstName)
.ToList();

Filter documents by a mapped nested field​

The index maps the nested document field Address.Location.Latitude to an index-field named Latitude.
Use Latitude in the query:

List<Employee> employees = session.Advanced
.DocumentQuery<Employee, Employees_ByFieldPresence>()
.WhereExists("Latitude")
.ToList();

Find documents that are MISSING a field​

Dynamic query​

  • Use .Not.WhereExists to return documents that are missing the specified field.
  • You can check for a missing field using either a field name or a nested field path, as shown below.

Filter documents by field name​

The following query returns employees whose documents do not contain the field FirstName:

List<Employee> employeesWithoutFirstName = session.Advanced
.DocumentQuery<Employee>()
.Not.WhereExists("FirstName")
// Or use a lambda expression: .Not.WhereExists(e => e.FirstName)
.ToList();

In RQL, not cannot appear immediately after where.
Use where true and not exists(...) when the missing-field condition is the first condition.
DocumentQuery adds true and automatically in this case.

Filter documents by nested field path​

Use the full path to check for a missing nested field.
The following query returns employees whose documents do not contain Latitude at Address.Location.Latitude:

List<Employee> employeesWithoutLatitude = session.Advanced
.DocumentQuery<Employee>()
.Not.WhereExists("Address.Location.Latitude")
// Or use a lambda expression:
// .Not.WhereExists(e => e.Address.Location.Latitude)
.ToList();

Static index query​

  • Use .Not.WhereExists with the index-field name.
    The field you want to check must be included in the index's map function.

  • The index must also retain an entry for documents that are missing that field. The index used in this article maps the document ID to Id, ensuring that an entry is retained even when both FirstName and Latitude are missing.

  • Alternatively, set Indexing.IndexEmptyEntries to true to retain entries for documents that are missing all mapped fields, without needing to map Id for this purpose.

If Indexing.IndexMissingFieldsAsNull is true, missing mapped fields are indexed as null and count as present.
Consequently, .Not.WhereExists does not return documents whose missing fields were indexed this way.
This setting does not affect auto-indexes.


Filter documents by field name​

Query the Employees_ByFieldPresence index defined above:

List<Employee> employeesWithoutFirstName = session.Advanced
.DocumentQuery<Employee, Employees_ByFieldPresence>()
.Not.WhereExists("FirstName")
// Or use a lambda expression: .Not.WhereExists(e => e.FirstName)
.ToList();

Filter documents by a mapped nested field​

The index maps the document field Address.Location.Latitude to an index-field named Latitude.
The following query checks the Latitude index-field and returns employee documents that do not contain Latitude at Address.Location.Latitude:

List<Employee> employeesWithoutLatitude = session.Advanced
.DocumentQuery<Employee, Employees_ByFieldPresence>()
.Not.WhereExists("Latitude")
.ToList();

How field presence is determined​

  • WhereExists checks field presence in the index used by the query:

    • An explicit null counts as present only when it is the value of the field you check.
    • If a parent on a nested path is missing or null, the field counts as missing.
    • An empty array counts as missing.
  • These rules apply to both query types, with a configuration exception for static indexes:

    • For dynamic queries, they apply to the document field name or nested path specified in the query.

    • For static index queries, presence is checked on the fields produced by the index's map function.
      For example, with the direct index-field mapping Latitude = employee.Address.Location.Latitude,
      the query checks Latitude, not Address.Location.Latitude.

      If Address is missing or null, this mapping produces an implicit null for Latitude,
      which is not indexed by default. The Latitude index-field therefore counts as missing.

      The Indexing.IndexMissingFieldsAsNull configuration key is false by default.
      If set to true, missing mapped fields are indexed as null and count as present.
      Empty arrays still count as missing, regardless of this setting.

      For .Not.WhereExists to return documents with missing fields, the index must retain entries for them.
      See Static index query for missing fields for details.


The following examples use document field names and paths and assume the default indexing settings.
For static indexes, they assume direct mappings and retained entries for documents with missing fields,
as explained above.

Document contentChecked pathWhereExists result.Not.WhereExists result
"FirstName": nullFirstNameDocument returned ✅Document excluded ❌
No FirstName fieldFirstNameDocument excluded ❌Document returned ✅
"Territories": []TerritoriesDocument excluded ❌Document returned ✅
"Address": { "Location": { "Latitude": null } }Address.Location.LatitudeDocument returned ✅Document excluded ❌
"Address": nullAddress.Location.LatitudeDocument excluded ❌Document returned ✅
"Address": { "City": "Seattle" }Address.Location.LatitudeDocument excluded ❌Document returned ✅

Syntax​

WhereExists​

IDocumentQuery<T> WhereExists(string fieldName);

IDocumentQuery<T> WhereExists<TValue>(Expression<Func<T, TValue>> propertySelector);
ParameterTypeDescription
fieldNamestringFor a dynamic query, the document field name or nested path.
For a static index query, the index field name.
propertySelectorExpression<Func<T, TValue>>A lambda expression that selects the field. For static index queries, the resulting field name must match a field in the index.

Not​

The Not property negates the next filtering condition.
Place it immediately before WhereExists to search for missing fields:

.Not.WhereExists("FirstName")

RQL​

// Find documents with the field.
where exists(FieldName)

// Find documents without the field.
where true and not exists(FieldName)

In this article