字段上的 Firestore 查询顺序与不同字段上的过滤器

Lon*_*gLv 4 java firebase google-cloud-firestore

我在 google Cloud Firestore 中的查询条件有问题。

任何人都可以帮助我。

这是我的收藏和文件

以下是我获取第一个以 HA_ 开头的文档并按 ID DESC 排序的代码

public Article getLastArticleProvider() {
    ApiFuture<QuerySnapshot> query = firebaseDB.getTblArticles()
            .whereGreaterThanOrEqualTo("articleId", "HA_")
            .orderBy("id", Query.Direction.DESCENDING)
            .limit(1)
            .get();

    QuerySnapshot snapshotApiFuture;
    Article article = null;

    try {
        snapshotApiFuture = query.get();
        List<QueryDocumentSnapshot> documents = snapshotApiFuture.getDocuments();
        for (QueryDocumentSnapshot document : documents) {
            article = document.toObject(Article.class);
        }
    } catch (InterruptedException | ExecutionException e) {
        return null;
    }
    return article;
}
Run Code Online (Sandbox Code Playgroud)

我想获取文章的最后一个 ID,文章 ID 以“HA_”或“XE_”开头

例如上图:

  • if(articleId start with "HA_") => 返回 id 831 的对象
  • if(articleId start with "XE_") => 返回 id 833 的对象

现在我收到一个错误

java.util.concurrent.ExecutionException:com.google.api.gax.rpc.InvalidArgumentException:io.grpc.StatusRuntimeException:INVALID_ARGUMENT:不等式过滤器属性和第一个排序顺序必须相同:articleId 和 id

gen*_*ser 5

TL; 博士

在您的不等式过滤器属性之后添加一个虚拟订单并更改您的查询优先级以满足您的需求。

我在 javascript 上遇到了同样的问题,但我相信这是 java 的解决方案。

完整解决方案:

当我运行查询时:

module.exports.getLastGroupChat = async function (groupId) {
    let colRef = db.collection('messages')
    colRef = colRef.where('groupId', '==', groupId)
    colRef = colRef.where('userId', '!=', '')
    colRef = colRef.orderBy('timestamp', 'desc').limit(1)
    const doc = await colRef.get()
    return doc
Run Code Online (Sandbox Code Playgroud)

}

并收到:

不等式过滤器属性和第一排序顺序必须相同:userId 和timestamp

为了解决这个问题,首先我必须在不等式过滤器之后添加一个具有相同不等式属性的排序顺序。

此外,为了实现不等式属性的虚拟排序顺序,我必须更改查询优先级。

注意:您可以where -> order -> where -> order在同一个查询上运行!

module.exports.getLastGroupChat = async function (groupId) {
    let colRef = db.collection('messages')
    colRef = colRef.where('userId', '!=', '')
    colRef = colRef.orderBy('userId', 'desc')
    colRef = colRef.where('groupId', '==', groupId)
    colRef = colRef.orderBy('timestamp', 'desc').limit(1)
    const doc = await colRef.get()
    return doc
}
Run Code Online (Sandbox Code Playgroud)

该查询在我的本地调试 Firestore 上运行得非常完美。将您的更改推送到您的 Firebase 云函数并触发您的函数。检查您的函数日志,您可能会收到索引错误。

查询需要索引。您可以在此处创建它:https : //console.firebase.google.com/v1/r/project..

确保您进入链接并构建索引。大约需要五到十分钟才能生效。然后再次运行您的功能,一切都应该没问题。

玩得开心!:)


Ale*_*amo 3

正如下面的错误所说:

不等式过滤器属性和第一排序顺序必须相同:articleId 和 id

因此,在您的情况下,您无法使用不同的属性来过滤元素并同时对它们进行排序articleIdid

官方文档中还有一个如何这样做的示例:

因此,要解决此问题,您应该对同一文档属性进行过滤和排序。