我正在使用Firestore数据库和FirebaseUI将结果加载到android kotlin中的回收器视图中。我遇到了一些奇怪的事情。
当在不同的字段上进行太多不同的请求时,我理解错误“查询需要索引”。但是,我知道您可以发出许多请求whereEqualTo以及一个请求orderBy。现在,当我自己发出此请求时(不使用FirestoreRecyclerOptions)。我没问题,效果很好。
但是,当我将请求与FirestoreRecyclerOptions一起使用时,例如:
var querySearch = FirebaseFirestore.getInstance()
.collection(DB_DEALS_COLLECTION).document(departureCountry.toString()).collection(DB_DEALS_SUB_COLLECTION)
.whereEqualTo(FILTER_FIELD_APR, true)
.whereEqualTo(FILTER_FIELD_AUG, true)
.whereEqualTo(FILTER_FIELD_DEC, true)
.orderBy(FILTER_FIELD_TIMESTAMP, Query.Direction.DESCENDING).limit(15)
val options = FirestoreRecyclerOptions.Builder<Deal>().setQuery(querySearch, Deal::class.java).build()
我收到此错误:
[Firestore]: Listen for Query(target=Query(deals_collection/USA/deals where monthApr == true and monthAug == true and monthDec == true order by -timestamp, -__name__);limitType=LIMIT_TO_FIRST) failed: Status{code=FAILED_PRECONDITION, description=The query requires an index.
现在,有两件事很奇怪: 1.根据我的检查,实际上我的recyclerview中显示了正确的结果。但我担心为什么收到此消息,并且我不想将来出现不正确的结果。 2.当我单击控制台中的链接以添加索引时,我在Firestore控制台中得到以下消息以添加:我必须使用以下字段创建一个复合索引:
monthApr Ascending
monthAug Ascending
monthDec Ascending
timestamp Descending
现在我再也不想让这些字段递增,仅是时间戳记?
注意:只有在包含以下内容时才会发生这种情况:
.orderBy(FILTER_FIELD_TIMESTAMP,
我也在控制台中看到limitType=LIMIT_TO_FIRST
。我也看到-__name__
。这些是什么,我从没设置过!
我希望我的问题很清楚,我对此感到有点困惑。
谢谢!
答案 0 :(得分:0)
如果您的查询确实需要索引,则应该可以通过覆盖FirebaseRecyclerAdapter
中的the error callback来轻松创建它:
FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<T, H>(options) {
// ...
@Override
public void onError(@NonNull FirebaseFirestoreException e) {
Log.w(TAG, "onError", e);
}
};
然后在您的logcat中,您将看到完整的错误,其中包括一个链接,您可以单击该链接来自动创建丢失的索引。
关于您的其他问题:
RecyclerView
中看到数据。它来自不使用索引的脱机缓存。.limit(15)
是.limitToFirst(15)
的较不冗长的说法。因此您可以忽略limitType=LIMIT_TO_FIRST
。__name__
是文档ID的特殊保留字段。您所做的每个查询最后都按__name__
进行排序,这样即使您的其他orderBy
子句上有平局,您也始终会以相同的顺序获得结果。