针对多个属性使用范围和不等式过滤条件的查询概览

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 [...]) 索引。因此,它可以快速且经济实惠地 查询在 experience 之前对 salary 进行排序,如以下示例所示:

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 添加到 order by 子句中, 则 Datastore 模式 Firestore 将选择 (experience [...], salary [...]) 索引 用于计算查询结果。由于对广告素材没有其他限制 experience 时,Datastore 模式 Firestore 将读取 employees 集合,然后再应用 salary 过滤条件查找最终的 结果集。这意味着,不满足 salary 过滤条件的索引条目仍会被读取,从而导致查询的延迟时间和费用增加。

价格

对多个属性使用范围和不等式过滤条件的查询会产生费用 根据读取的实体和读取的条目索引。

如需了解详细信息,请参阅价格页面。

限制

除了查询限制之外,在添加之前,请注意以下限制 将带有范围和不等式过滤条件的查询用于多个属性:

  • 为防止查询运行费用过高,Datastore 模式 Firestore 将范围或不等式运算符的数量限制为 10。

后续步骤