筛选器传入查询
Overview
筛选器修改传入的 MongoDB 查询,仅返回与查询匹配的结果的子集。在集合中添加筛选器,支持您控制查询文档的形状并提高查询性能。
在 Atlas App Services 运行查询之前,筛选器会添加其他查询参数并省略查询结果中的字段。每个筛选器包含三个组件:
App Services 如何应用筛选器
在适用规则的情况下,App Services 评估所有 MongoDB 请求并应用筛选器(Device Sync 请求除外)。可筛选 MongoDB 请求的示例包括:
集合查询。
文档写入。
如果在给定请求上下文的情况下,筛选器的“apply when”表达式计算结果为真,则此筛选器将应用于给定请求。如果筛选器应用于请求,则 App Services 会将筛选器的查询或投影合并到所请求操作的现有查询和投影中。
可将多个筛选器应用于单个请求。
App Services 在将请求发送到 MongoDB 之前对请求应用筛选器。
例子
一个集合包含数百万个文档,并且提供一个具有以下“apply when”表达式的角色:
{ "owner_id": "%%user.id" }
如果没有应用筛选器,则 App Services 将为查询匹配的每个文档评估角色。我们知道,App Services 将保留任何没有将用户 id 作为 owner_id
字段值的文档,因此我们在 App Services 评估任何角色之前,应用额外的查询谓词来排除这些文档,从而节省时间和计算资源:
Apply When | 查询 | 投射 |
---|---|---|
{ "%%true": true } | { "owner_id": "%%user.id" } | {} |
定义筛选器
你可以使用筛选器来优化查询、最大限度减少计算开销并保护敏感数据。筛选器对于影响部分或全部查询的跨领域问题最有用。
如果您希望集中式系统能够执行以下操作,请考虑使用筛选器:
将查询限制为所有文档的子集
省略敏感数据或未使用的字段
例子
在一个投票应用程序中,有些用户同意匿名分享投票,对于这种情况,您可以使用以下筛选器将所有查询的范围限制为现有数据的一个匿名子集:
{ "name": "AnonymizeVotes", "apply_when": true, "query": { "shareVoteAnonymous": true }, "project": { "_id": 0, "age": 1, "vote": 1 } }
{ "_id": ObjectId(...), "name": "sarah", age: 42, "vote": "yes", "shareVoteAnonymous": true } { "_id": ObjectId(...), "name": "andy", age: 22, "vote": "no", "shareVoteAnonymous": true } { "_id": ObjectId(...), "name": "jennifer", age: 37, "vote": "yes", "shareVoteAnonymous": false } { "_id": ObjectId(...), "name": "rick", age: 43, "vote": "no", "shareVoteAnonymous": true } { "_id": ObjectId(...), "name": "tom", age: 64, "vote": "yes", "shareVoteAnonymous": false } { "_id": ObjectId(...), "name": "bob", age: 67, "vote": "yes", "shareVoteAnonymous": true }
{ age: 42, "vote": "yes" } { age: 22, "vote": "no" } { age: 37, "vote": "yes" } { age: 43, "vote": "no" } { age: 64, "vote": "yes" } { age: 67, "vote": "yes" }
步骤
您可以通过 App Services 用户界面或使用 Realm CLI 部署配置文件,为关联集群中的特定集合定义筛选器:
注意
本指南需要一个关联 MongoDB Atlas 数据源。
指定 Apply When 表达式
在 Apply When 输入框中输入规则表达式,用于定义过滤器何时应用于查询。对于传入的查询,如果表达式计算结果为 true
,则 App Services 将 Filter Query 参数添加到传入查询。
重要
Atlas App Services 将在读取任何文档之前评估并应用过滤器,因此您无法在过滤器的 “Apply When” 表达式中使用 MongoDB 文档扩展。但是,您也可以使用其他扩展,如 %%user
、%%values
和 %function
。
指定过滤器投影
在Projection输入框中,指定一个包含投影文档的文档,以便在应用筛选器时合并到传入的查询中。
例如,保留文档中 career_stats
和 personal
字段的过滤器可以使用以下过滤器投影:
{ "career_stats": 0, "personal": 0 }
添加规则配置文件
要定义或修改集合的角色,请打开集合配置目录中的rules.json
配置文件。
提示
为collection搭建基架
如果尚未为collection定义规则或模式,则需要手动创建其配置目录和schema.json
:
# Create the collection's configuration directory mkdir -p data_sources/<service>/<db>/<collection> # Create the collection's schema file echo '{}' >> data_sources/<service>/<db>/<collection>/rules.json
配置文件应具有以下通用格式:
{ "database": "<Database Name>", "collection": "<Collection Name>", "roles": [], "filters": [] }
注意
联合数据源不支持规则或模式。只能通过系统函数访问联合数据源。
添加一个或多个筛选器
向要配置的每个筛选器的filters
数组添加一个文档。筛选器文档具有以下形式:
{ "name": "<Filter Name>", "apply_when": { Expression }, "query": { MongoDB Query }, "projection": { MongoDB Projection } }
字段 | 说明 | |
---|---|---|
name string | 必需。过滤器的名称。过滤器名称用于识别和区分过滤器。限制在 100 个字符以内。 | |
apply_when object | 一个表达式,用于确定此筛选器何时应用于传入的 MongoDB 操作。 重要Atlas App Services 将在读取任何文档之前评估并应用过滤器,因此您无法在过滤器的 “Apply When” 表达式中使用 MongoDB 文档扩展。但是,您也可以使用其他扩展,如 | |
query object Default: {} | 一个MongoDB查询, Atlas App Services将其合并到已筛选操作的现有查询中。 例子筛选器使用以下查询保留
| |
projection object Default: {} | 一种MongoDB投影, Atlas App Services将其合并到已筛选操作的现有投影中。 重要投影冲突MongoDB 投影可以是包含式的或排除式的,即可以仅返回指定的字段,或者不返回未指定的字段。如果多个过滤器应用于查询,这些过滤器必须全部指定相同类型的投影,否则查询会失败。 例子过滤器使用以下投影从所有文档中保留
|
注意
App Services 过滤器的安全注意事项
虽然基于角色的权限和过滤器可以隐藏集合中的特定文档和字段,但如果系统允许任意查询访问该集合,则可能会泄露数据。
例如,根据集合中存储的值引发错误(例如被零除错误)的查询或函数可能会泄露有关文档的信息,即使角色或过滤器禁止查询用户直接查看文档也是如此。用户还可以通过其他方法对基础数据进行推断(例如,测量查询执行时间,这可能会受到数据分布情况的影响)。
请注意这种可能性,并在必要时对数据访问模式进行审核。