这是我的查询:
db.requests
.where('userId', '==', uid)
.where('placeId', '==', placeId)
.where('endTime', '>=', Date.now())
.where('isFullfilled', '==', false);
所以我在 firestore.indexes.json
中手动编写了这个索引:
{
"collectionGroup": "requests",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "userId",
"order": "ASCENDING"
},
{
"fieldPath": "placeId",
"order": "ASCENDING"
},
{
"fieldPath": "endTime",
"order": "ASCENDING"
},
{
"fieldPath": "isFullfilled",
"order": "ASCENDING"
}
]
},
运行时,我收到错误“此查询需要索引”。自动创建的索引如下所示:
另一方面,我手动创建的索引在 GUI 中看起来像这样:
为什么它不接受我自己的索引?字段的顺序重要吗?我没有对查询结果进行排序。索引创建有什么模式吗?这真的很令人困惑,我在文档中找不到任何相关内容。必须针对云数据库运行每个查询才能获得正确的复合索引字段顺序,这确实很烦人。
最佳答案
Does the order of fields matter?
是的,字段的顺序对于结果索引非常重要。我几乎看到这样的索引:
- Firestore 通过连接索引中的字段值,为每个文档创建一个复合值。
- 对于查询,它只能查询字段和顺序是否完全匹配(字段子集有一些异常(exception),以及可以执行 zig-zag-merge-join 的情况)。
- 对于此类查询,Firestore 会查找索引中与条件匹配的第一个条目。然后,它从那里返回连续的结果(有时称为切片)。它不会跳过任何文档,也不会跳转到索引中的另一个点,也不会反转索引。
- 您进行排序或执行范围查询(您的
>=
)的字段必须位于索引中的最后一个。
请注意,这可能不是它真正的工作原理,但该模型保持得很好 - 事实上,这也是我们建议在 Firebase 的其他数据库上实现多字段过滤的方式,如下所述:Query based on multiple where clauses in Firebase
关于firebase - firestore复合索引中字段的顺序是如何决定的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68217144/