Firebase Firestore - OR 查询

Posted

技术标签:

【中文标题】Firebase Firestore - OR 查询【英文标题】:Firebase Firestore - OR query 【发布时间】:2018-03-25 09:34:00 【问题描述】:

如何通过一个字段的多个值获取数据?例如,我有一个包含帖子的数据库,我想查询 blogId 为 1 或 2 的所有帖子,按时间戳排序。

collection("posts").whereEqualTo("blogId", "1")
.whereEqualTo("blogId", 2).orderBy("timestamp", Query.Direction.DESCENDING).limit(50)

上面的代码不起作用:(

如何做到这一点? 问候:)

【问题讨论】:

由于 11 月 7 日的更新,现在可以做到这一点。请更新接受的答案:***.com/a/59039919/2057171 【参考方案1】:

Firestore now supports "IN" queries 用于此目的。

查询如下所示:

database.collection("collectionName").where("fieldName", "in", ["fieldValue1", "fieldValue2"]);

您最多可以有 10 个值 (fieldValueX) 来检查“IN”。


所需的代码 OP 如下:

database.collection("posts").where("blogId", "in", ["1", "2"]); 

【讨论】:

多个字段呢? @IsraelObanijesu 据我了解,您必须为此使用复合查询,但值得检查 firebase 文档以确保。我不太会处理这样的查询 很好的答案,尽管这在 Firebase 方面的实现非常糟糕,并且严格限制了 10 个值...【参考方案2】:

你可以合并 Observables 并作为一个返回

orQuery()

    const $one = this.afs.collection("posts", ref => ref.where("blogId","==","1")).valueChanges();
    const $two = this.afs.collection("posts", ref => ref.where("blogId","==","2")).valueChanges();

    return combineLatest($one,$two).pipe(
        map(([one, two]) => [...one, ...two])
    )


getOr()
    this.orQuery().subscribe(data => console.log(data))

【讨论】:

请注意,在这种方法中,最终结果可能包含重复项,具体取决于查询(在这种确切情况下,不会有重复项,因为相同的字段用于具有不同值的查询)。 如果我们使用多个字段(例如您的答案)对数据进行分页,可能会很困难。【参考方案3】:

Firebase 已听取了我们的请求,其中包含来自 7 Nov, 2019IN 查询。这是一种OR 查询,您最多可以有10 OR 过滤器。

对于安卓:

collection("posts").whereIn("blogId", Arrays.asList("1", "2"))
.orderBy("timestamp", Query.Direction.DESCENDING).limit(50);

Firebase documentation

【讨论】:

应该是正确答案【参考方案4】:

OR 运算符在 firebase firestore 中不被接受:

Cloud Firestore 对逻辑 OR 查询提供有限的支持。 in 和 array-contains-any 运算符支持单个字段上最多 10 个相等 (==) 或数组包含条件的逻辑 OR。对于其他情况,请为每个 OR 条件创建单独的查询,并在您的应用中合并查询结果。

Queries in Cloud Firestore, Query limitations

通常使用 firebase 语法,您可以调用两个集合:

const res1 = async collection("posts", ref => ref.where('blogId', '==', 1).get();
const res2 = async collection("posts", ref => ref.where('blogId', '==', 2).get();

您可以在提供给视图之前合并结果。

但在这种情况下,如果您有 blogId,您可以使用以下语法: collection("posts").orderBy('blogId').startAt(1).endAt(2);

e.d

【讨论】:

【参考方案5】:

我找不到任何关于 OR 条件的文档。但是您可以将您对blogId 的要求改写如下:

WHERE blogId > 0 AND blogId < 3

试试这个代码:

collection("posts")
.where("blogId", ">", "0")
.where("blogId", "<", "3")
.orderBy("timestamp", Query.Direction.DESCENDING)
.limit(50)

【讨论】:

是的,但我的情况稍微复杂一些。我有一个应用程序,用户可以在其中订阅一些博客。所以我需要检索几个 id 的所有最新帖子(它可以是 2,5 或更多 id)。 id 是自动生成的(例如 wordpress - 831cacax613das)或来自博主(对于 blogspot 博客 - 12320183127312307212)。我目前正在使用带有 elasticsearch 的 firebase 数据库,但我有兴趣迁移到 Firestore。 在此处查看如何使用集合:cloud.google.com/firestore/docs/solutions/arrays 嗯,我可以使用单个元素映射存储 blogId 并像示例中一样查询它,但在这种情况下,每个 blogId 都需要单独的索引。目前我的数据库中有 300 个博客,但如果我有几千个呢? :D 即使我将使用整数值而不是布尔值将其存储在地图中,我也只能使用一个字段进行查询,因此无法调用它: .whereGreaterThan("blogIdMap.kqy04zya72zit5x7n9", 0) .whereGreaterThan("blogIdMap.kqy0n2dt2maqluvi3eu ", 10) 是的,这似乎是个问题。你能加入一个有这些 ID 的表吗? 不,目前我将 blogId 作为普通字段 (blogId = 123131) 存储在帖子实体中。但是,用户有订阅博客的地图(123131 = true)。我正在考虑将查询可观察对象合并为一个,但这不是一个好主意,因为我想获得 f.e. 10 个最新帖子。而且我会失去分页能力。【参考方案6】:

Firestore 没有 OR 查询。他们这样做的方式是运行两个查询并将它们拼接起来。

你可以例如:

const search = ( key, value ) =>  collection( 'users' ).where( key, '==', value ).get().then( doc => doc.data() )

Promise.all( [ search( 'name', 'John' ), search( 'name', 'Johnny' ) ] )
.then( ( [ one, two ] ) => one.concat( two ) )
.then( allResults => dothings() )

【讨论】:

【参考方案7】:

对于 android,我正在使用这样的 OR 查询。

List<String> values = new ArrayList<>();
    values.add("Value 1");
    values.add("Value 2");

然后像这样使用 .whereIn 查询。

db.collection("collectionName")
            .whereIn("fieldName", values)   // where values is the list we created
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() 
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) 

                    if (task.isSuccessful()) 

                      // Do your stuff

                    

                
            );

【讨论】:

【参考方案8】:

试试这个

collection("posts").start("blogId", "1")
.end("blogId", 2).orderBy("timestamp", Query.Direction.DESCENDING).limit(50)

【讨论】:

【参考方案9】:

您可以使用De Morgaan's 法则将AND 查询重写为OR 查询。

【讨论】:

它仍然是两个quieres。 我可能弄错了,但这适用于XOR 而不是OR 对吗? 你错了?

以上是关于Firebase Firestore - OR 查询的主要内容,如果未能解决你的问题,请参考以下文章

使用Firestore需要firebase-firestore.js文件吗?

无法在firebase.firestore.CollectionReference中使用Array firebase.firestore.Query为什么?

(firebase.firestore 不是函数)尝试在 Firestore 中创建集合时

Firestore 配置 - Firebase

firebase2.default.firestore 不是一个函数 - React Firebase

忽略 firebase.firestore.timestamp