Datastore 模式 Firestore 支持在单个查询中对多个属性使用范围和不等式过滤条件。借助此功能,您可以对多个属性使用范围和不等式条件,并可通过将后过滤逻辑的实现委托给 Datastore 模式 Firestore 来简化应用开发。
针对多个属性的范围和不等式过滤器
以下查询对优先级和天数使用范围过滤条件,以返回所有任务 。
Go
query := datastore.NewQuery("Task").
FilterField("priority", ">", 4).
FilterField("days", "<", 3).
GQL
SELECT * FROM /tasks WHERE priority > 4 AND days < 3;
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("Task")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("priority", 4), PropertyFilter.lt("days", 3)))
.build();
Node.js
const query = datastore
.createQuery('Task')
.filter(
and([
new PropertyFilter('priority', '>', 4),
new PropertyFilter('days', '<', 3),
])
);
Python
from google.cloud import datastore
client = datastore.Client()
query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("priority", ">", 4))
query.add_filter(filter=PropertyFilter("days", "<", 3))
PHP
$query = $datastore->query()
->kind('Task')
->filter('priority', '>', 4)
->filter('days', '<', 3)
C#
Query query = new Query("Task")
{
Filter = Filter.And(Filter.GreaterThan("priority", 4),
Filter.LessThan("days", 3))
};
Ruby
query = datastore.query("Task")
.where("priority", ">", 4)
.where("days", "<", 3)
索引编制注意事项
在开始运行查询之前,请确保您已阅读 查询。
如果未指定 ORDER BY
子句,则 Datastore 模式 Firestore 会使用任何可满足查询过滤条件的索引来处理查询。这种方法会产生一个
根据索引定义进行排序。
如需优化 Datastore 模式 Firestore 查询的性能和费用,请优化索引中属性的顺序。为此,请确保您的 索引从左到右排序,以便查询提取为 数据集。
例如,假设您想要搜索某个员工集合,
查找薪资超过 10 万美元的美国员工,
年经验值大于 0。基于您对该数据集的了解,您知道该薪水限制条件要比经验限制条件更为严苛。会减少索引扫描次数的索引是
(salary [...], experience [...])
索引。因此,为了提高查询速度并使其更加经济高效,应将 salary
排在 experience
之前,如下所示:
GQL
SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("salary"), OrderBy("experience"))
.build();
Node.js
const query = datastore
.createQuery("employees")
.filter(
and([
new PropertyFilter("salary", ">", 100000),
new PropertyFilter("experience", ">", 0),
])
)
.order("salary")
.order("experience");
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.add_filter("experience", ">", 0)
query.order = ["-salary", "-experience"]
索引优化最佳实践
优化索引时,请遵循以下最佳实践。
对查询进行排序,先是等式,其后是选择性最强的范围或不等式字段
Datastore 模式 Firestore 会使用复合索引最左侧的属性来满足对 orderBy()
查询的第一个字段使用的等式限制条件及范围和不等式限制条件(如果有)。这些限制条件会减少
将 Datastore 模式 Firestore 扫描的条目编入索引。Datastore 模式 Firestore 会使用
索引的属性,以满足
查询。虽然这些限制条件不会减少 Datastore 模式下 Firestore 扫描的索引条目数,但会滤除不匹配的实体,从而减少返回给客户端的实体数量。
如需详细了解如何创建高效索引,请参阅索引结构和 定义和优化索引。
将属性按查询限制条件的严苛程度降序排列
为了确保 Datastore 模式 Firestore 为您的查询选择最佳索引,
指定根据范围和不等式属性对范围和不等式属性进行排序的 orderBy()
子句
这些限制条件在查询中的选择性程度如何?
选择性。选择性越高,匹配的实体就越少,选择性越低
匹配更多实体。在索引排序中,将选择性更高的范围和不等式属性放在选择性较低的属性之前。
尽可能减少 Datastore 模式 Firestore 扫描和返回的实体数量 网络,则应始终按查询的降序对属性进行排序 约束条件选择性。如果结果集未按所需顺序排序,并且预计结果集较小,则您可以实现客户端逻辑来按所需顺序对其重新排序。
例如,如果您想搜索一批员工 查找薪资超过 10 万美元的美国员工,并按 员工工作年限。如果您预计只有少数员工的薪水会超过 10 万美元,那么可按如下所示编写高效的查询:
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(PropertyFilter.gt("salary", 100000))
.setOrderBy(OrderBy("salary"))
.build();
QueryResults<Entity> results = datastore.run(query);
// Order results by `experience`
Node.js
const query = datastore
.createQuery("employees")
.filter(new PropertyFilter("salary", ">", 100000))
.order("salary");
const [entities] = await datastore.runQuery(query);
// Order results by `experience`
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.order = ["salary"]
results = query.fetch()
// Order results by `experience`
将 experience
的排序添加到查询将产生相同的集合
实体,并避免对客户端上的结果重新排序,则查询可能
与前一个查询相比,读取的无关索引条目要多得多。这是因为
Datastore 模式 Firestore 始终优先选择索引属性前缀与
查询的排序依据子句。如果将 experience
添加到排序依据子句,则 Datastore 模式 Firestore 会选择使用 (experience [...], salary [...])
索引来计算查询结果。由于对广告素材没有其他限制
experience
时,Datastore 模式 Firestore 将读取
employees
集合,然后再应用 salary
过滤条件查找最终的
结果集。这意味着,不满足 salary
过滤条件的索引条目仍会被读取,从而导致查询的延迟时间和费用增加。
价格
对多个属性使用范围和不等式过滤条件的查询是根据所读取的实体数和索引条目数来收费的。
如需了解详细信息,请参阅价格页面。
限制
除了查询限制之外,在使用对多个媒体资源使用范围和不等式过滤条件的查询之前,还应注意以下限制:
- 为防止查询运行费用过高,Datastore 模式 Firestore 将范围或不等式运算符的数量限制为 10。
后续步骤
- 了解如何优化查询。
- 详细了解如何执行简单查询和复合查询。
- 了解 Datastore 模式 Firestore 如何使用索引。