Filter Query Results
-
One of the most basic functionalities of querying is the ability to filter out data and return records that match a given condition.
-
The following examples demonstrate how to add simple conditions to a query:
Where - equals
// Basic filtering using "whereEquals":
// ====================================
const filteredEmployees = await session
// Query an index
.query({ indexName: "Employees/ByFirstAndLastName" })
// The filtering predicate
.whereEquals("FirstName", "Robert")
// By default AND is applied between both 'where' predicates
.whereEquals("LastName", "King")
// Execute the query, send it to the server for processing
.all();
// Results will include all Employee documents
// with FirstName equals to 'Robert' AND LastName equal to 'King'
class Employees_ByFirstAndLastName extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("employees", employee => {
return {
FirstName: employee.FirstName,
LastName: employee.LastName
};
});
}
}
from index "Employees/ByFirstAndLastName"
where FirstName == "Robert" and LastName == "King"
Where - numeric Property
// Filter with "whereGreaterThan":
// ===============================
const filteredProducts = await session
// Query an index
.query({ indexName: "Products/ByUnitsInStock" })
// The filtering predicate
.whereGreaterThan("UnitsInStock", 20)
.all();
// Results will include all Product documents having 'UnitsInStock' > 20
class Products_ByUnitsInStock extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("products", product => {
return {
UnitsInStock: product.UnitsInStock
};
});
}
}
from index "Products/ByUnitsInStock"
where UnitsInStock > 20
// Filter with "whereLessThan":
// ============================
const filteredProducts = await session
// Query an index
.query({ indexName: "Products/ByUnitsInStock" })
// The filtering predicate
.whereLessThan("UnitsInStock", 20)
.all();
// Results will include all Product documents having 'UnitsInStock'< 20
class Products_ByUnitsInStock extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("products", product => {
return {
UnitsInStock: product.UnitsInStock
};
});
}
}
from index "Products/ByUnitsInStock"
where UnitsInStock < 20
Where - nested property
// Filter by a nested property:
// ============================
const filteredOrders = await session
// Query a collection
.query({ collection: "Orders" })
// Filter by the nested property 'ShipTo.City' from the Order document
.whereEquals("ShipTo.City", "Albuquerque")
.all();
// * Results will include all Order documents with an order that ships to 'Albuquerque'
// * An auto-index will be created
from "Orders"
where ShipTo.City == "Albuquerque"
Where - multiple values
// Filter by multiple values:
// ==========================
const filteredOrders = await session
// Query an index
.query({ indexName: "Orders/ByProductNamesPerOrderLine" })
// Filter by multiple values
.whereEquals("ProductName", "Teatime Chocolate Biscuits")
.all();
// Results will include all Order documents that contain ALL values in "Teatime Chocolate Biscuits"
class Orders_ByProductNamesPerOrderLine extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("orders", order => {
return {
// Index field 'ProductNames' will contain the product names per Order Line
ProductNames: order.Lines.map(x => x.ProductName)
};
});
}
}
from index "Orders/ByProductNamesPerOrderLine"
where ProductNames == "Teatime Chocolate Biscuits"
Where - in
Use whereIn
when you want to filter by a single value out of multiple given values.
// Filter with "whereIn":
// ======================
const filteredEmployees = await session
// Query an index
.query({ indexName: "Employees/ByFirstAndLastName" })
// The filtering predicate
.whereIn("FirstName", [ "Robert", "Nancy" ])
.all();
// Results will include all Employee documents that have either 'Robert' OR 'Nancy' in their 'FirstName' field
class Employees_ByFirstAndLastName extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("employees", employee => {
return {
FirstName: employee.FirstName,
LastName: employee.LastName
};
});
}
}
from index "Employees/ByFirstAndLastName"
where FirstName in ("Robert", "Nancy")
Where - containsAny
Use containsAny
to check if an enumeration contains any of the values from the specified list.
// Filter with "containsAny":
// ==========================
const filteredOrders = await session
// Query an index
.query({ indexName: "Orders/ByProductNames" })
// The filtering predicate
.containsAny("ProductNames", ["Ravioli", "Coffee"])
.all();
// Results will include all Order documents that have either 'Ravioli' OR 'Coffee' in their order
class Orders_ByProductNames extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("orders", order => {
return {
// Index field 'ProductNames' will contain a list of all product names
ProductNames: order.Lines.flatMap(x => x.ProductName.split(" "))
};
});
}
}
from index "Orders/ByProductNames"
where ProductNames in ("ravioli", "coffee")
Where - containsAll
Use containsAll
to check if an enumeration contains all of the values from the specified list.
// Filter with "containsAll":
// ==========================
const filteredOrders = await session
// Query an index
.query({ indexName: "Orders/ByProductNames" })
// The filtering predicate
.containsAll("ProductNames", ["Ravioli", "Pepper"])
.all();
// Results will include all Order documents that have both 'Ravioli' AND 'Pepper' in their order
class Orders_ByProductNames extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("orders", order => {
return {
// Index field 'ProductNames' will contain a list of all product names
ProductNames: order.Lines.flatMap(x => x.ProductName.split(" "))
};
});
}
}
from index "Orders/ByProductNames"
where ProductNames all in ("ravioli", "pepper")
Where - startsWith
// Filter with "whereStartsWith":
// ==============================
const filteredProducts = await session
// Query a collection
.query({ collection: "Products" })
// The filtering predicate
.whereStartsWith("Name", "ch")
.all();
// * Results will include all Product documents with a name that starts with 'ch'
// * An auto-index will be created
from "Products"
where startsWith(Name, "ch")
Where - endsWith
// Filter with "whereEndsWith":
// ===========================
const filteredProducts = await session
// Query a collection
.query({ collection: "Products" })
// The filtering predicate
.whereEndsWith("Name", "es")
.all();
// * Results will include all Product documents with a name that ends with 'es'
// * An auto-index will be created
from Products
where endsWith(Name, 'ra')
Where - exists
-
To find all documents in a collection that have a specified field,
see How to Filter by Field Presence. -
To find all documents in a collection that don't have a specified field,
see How to Filter by Non-Existing Field.
Where - filter by ID
-
Once the property used in the
whereEquals
clause is recognized as an identity property of a given entity type,
and there aren't any other fields involved in the query predicate, then this query is considered a "Collection Query". -
Such collection queries that ask about documents with given IDs, or where identifiers start with a given prefix and don't require any additional handling like ordering, full-text searching, etc, are handled directly by the storage engine.
-
This means that querying by ID doesn't create an auto-index and has no extra cost.
In terms of efficiency, it is the same as loading documents withsession.load
usage.
// Filter by id:
// =============
const order = await session
// Query a collection
.query({ collection: "Orders" })
// The filtering predicate
.whereEquals("id", "orders/1-A")
.firstOrNull();
// * Results will include the Order document having ID 'orders/1-A'
// * An auto-index is NOT created
from "Orders"
where id() == "orders/1-A"
// Filter by whereStartsWith id:
// =============================
const filteredOrders = await session
// Query a collection
.query({ collection: "Orders" })
// The filtering predicate
.whereStartsWith("id", "orders/1")
.all();
// * Results will include all Order documents having ID that starts with 'orders/1'
// * An auto-index is NOT created
from "Orders"
where startsWith(id(), "orders/1")