Rya*_*anM 17 javascript firebase google-cloud-firestore
在Firestore中,如何在不为每个键创建索引的情况下执行涉及地图中的键的复合查询?
例如,考虑一个包含博客帖子的集合,每个博客帖子都有类别.
Post {
title: ..
...
categories: {
cats: true
puppies: true
}
}
Run Code Online (Sandbox Code Playgroud)
为了以分页方式查询特定类别中的帖子,我们将执行以下操作:
let query = db.collection(`/posts`)
.where(`categories.${categoryId}`, '==', true)
.orderBy('createdAt')
.startAfter(lastDate)
.limit(5);
Run Code Online (Sandbox Code Playgroud)
但似乎这需要每个类别的综合索引(categories.<categoryId>和createdAt).有没有办法解决?
就我而言,为每个类别创建复合索引是不可行的,因为类别是用户生成的,并且可能很容易超过200(Firestore中复合索引的限制).
Fra*_*len 12
据我所知,Firestore应该自动生成这些索引。在数组,列表和集合的文档页面上:
考虑这种替代数据结构,其中每个类别都是映射中的键,所有值均为true:
Run Code Online (Sandbox Code Playgroud)// Sample document in the 'posts' collection { title: "My great post", categories: { "technology": true, "opinion": true, "cats": true } }现在,很容易查询单个类别中的所有博客文章:
Run Code Online (Sandbox Code Playgroud)// Find all documents in the 'posts' collection that are // in the 'cats' category. db.collection('posts') .where('categories.cats', '==', true) .get() .then(() => { // ... }); )此技术依赖于Cloud Firestore为所有文档字段(甚至嵌套地图中的字段)创建内置索引的事实。
尽管where条件的左侧可能是可变的,但这并不能改变这些索引应该自动生成的事实(据我所知)。
可以通过将每个类别的值设置为要排序的内容来实现。Firestore的指南对此进行了介绍。
Post {
title: ..
...
categories: {
cats: createdAt
puppies: createdAt
}
}
let query = db.collection(`/posts`)
.where(`categories.${categoryId}`, '>', 0)
.orderBy(`categories.${categoryId}`)
.startAfter(lastDate)
.limit(5);
Run Code Online (Sandbox Code Playgroud)
现在 Firestore 允许array-contains运营商。
如果要过滤包含特定值的文档,请尝试此操作。
首先,将 Map 字段更改为 Array 字段。
Post {
title: ..
...
categories: [
cats,
puppies
]
}
Run Code Online (Sandbox Code Playgroud)
其次,对每个不同的字段使用array-contains和orderBy。
let query = db.collection(`/posts`)
.where('categories', 'array-contains', 'cats')
.orderBy('createdAt')
.startAfter(lastDate)
.limit(5);
Run Code Online (Sandbox Code Playgroud)
您可以array-contains从此处查看有关运营商的官方文档。
| 归档时间: |
|
| 查看次数: |
6705 次 |
| 最近记录: |