使用索引执行高效搜索。您可以查看search with Indexes 和there is a "cookbook" 的文档,了解一些不同的搜索示例。
有两种使用索引进行搜索的方法,你使用哪一种取决于你是搜索相等(完全匹配)还是不等式(大于或小于,例如)。
搜索平等
如果您需要完全匹配,请使用索引 terms。这在文档中是最明确的,这也不是你最初的问题,所以我不会在这里多说。但这里是一个简单的例子
给定具有此形状的用户文档
{
ref: Ref(Collection("User"), "1234"),
ts: 16934907826026,
data: {
name: "John Doe",
email: "jdoe@example.com,
age: 50,
monthly_salary: 3000
}
}
以及如下定义的索引
CreateIndex({
name: "users_by_email",
source: Collection("User"),
terms: [ { field: ["data", "email"] } ],
unique: true // user emails are unique
})
您可以使用...搜索完全匹配的Match function!
Get(
Match(Index("user_by_email"), "jdoe@example.com")
)
搜索不等式
搜索不等式更有趣也更复杂。它需要使用索引 values 和 Range function。
按照上面的文档,我们可以新建一个索引
CreateIndex({
name: "users__sorted_by_monthly_salary",
source: Collection("User"),
values: [
{ field: ["data", "monthly_salary"] },
{ field: ["ref"] }
]
})
请注意,我没有在上述索引中定义任何 terms。对于不等式来说,重要的还是values。我们还将 ref 作为一个值包含在内,因为我们稍后会需要它。
现在我们可以使用Range 来获取所有工资在给定范围内的用户。该查询将获取所有工资在 2000 年及以上的用户。
Paginate(
Range(
Match(Index("users__sorted_by_monthly_salary")),
[2000],
[]
)
)
组合索引
对于“或”运算,请使用Union function。
对于“AND”操作,请使用Intersection function。
Match 和 Range 等函数返回集合。其中一个非常重要的部分是确保当您将 Set 与 Intersection 之类的函数“组合”时,数据的形状是相同的。
对于没有values 的索引,使用具有相同形状的集合并不困难,它们默认为相同的单个参考值。
Paginate(
Intersection(
Match(Index("user_by_age"), 50), // type is Set<Ref>
Match(Index("user_by_monthly_salary, 3000) // type is Set<Ref>
)
)
当 Set 有不同的形状时,需要对其进行修改,否则 Intersection 将永远不会返回结果
Paginate(
Intersection(
Range(
Match(Index("users__sorted_by_age")),
[30],
[]
), // type is Set<[age, Ref]>
Range(
Match(Index("users__sorted_by_monthly_salary")),
[2000],
[]
) // type is Set<[salary, Ref]>
)
)
{
data: [] // Intersection is empty
}
那么我们如何改变 Set 的形状以便它们可以相交呢?我们可以使用Join function 和Singleton function。
Join 将对集合中的所有条目运行操作。我们将使用它来仅返回一个参考。
Join(
Range(Match(Index("users__sorted_by_age")), [30], []),
Lambda(["age", "ref"], Singleton(Var("ref")))
)
总之:
Paginate(
Intersection(
Join(
Range(Match(Index("users__sorted_by_age")), [30], []),
Lambda(["age", "ref"], Singleton(Var("ref")))
),
Join(
Range(Match(Index("users__sorted_by_monthly_salary")), [2000], []),
Lambda(["age", "ref"], Singleton(Var("ref")))
)
)
)
组合索引的技巧
当提供不同的术语时,您可以使用额外的逻辑来组合不同的索引,或者使用绑定搜索缺失的字段。你可以做很多很酷的事情。
请查看cook book 和Fauna forums 以获取想法。
但是为什么!!!
这是个好问题!
考虑一下:由于 Fauna 是作为无服务器 API 提供的,因此您需要为对文档和索引的每次读取和写入以及执行查询的计算时间付费。 SQL 可以更容易,但它是一种更高级别的语言。 SQL 后面是一个查询规划器,它对如何获取数据做出假设。如果它不能有效地做到这一点,它可能会默认扫描您的整个数据表,或者执行比您预期的要昂贵得多的操作。
有了 Fauna,您就是查询计划者。这意味着入门要复杂得多,但这也意味着您可以很好地控制数据库的性能,从而控制您的成本。
我们正在努力改善定义架构和所需索引的体验,但目前您必须在低级别定义这些查询。