Firebase:查询以根据条件排除数据

Posted

技术标签:

【中文标题】Firebase:查询以根据条件排除数据【英文标题】:Firebase: Query to exclude data based on a condition 【发布时间】:2017-01-04 19:58:02 【问题描述】:

我可以使用 orderByChildequalTo 获取子节点中特定值的数据(很酷,它也适用于嵌套子节点)

private void getData() 
        try 
            final DatabaseReference database = FirebaseDatabase.getInstance().getReference();

            database.child(Constants.TABLE_TASKS).orderByChild("user/id")
                    .equalTo("somevalue")
                    .addValueEventListener(new ValueEventListener() 
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) 
                            Timber.d(dataSnapshot.toString());
                        

                        @Override
                        public void onCancelled(DatabaseError databaseError) 
                        
                    );
         catch (Exception ex) 
            ex.printStackTrace();
        
    

是否有一种简单的方法可以获取未找到特定值的数据,基本上类似于 notEqualTo("somevalue")

【问题讨论】:

删除了对 LIKE 的引用 清理 cmets。不过,恐怕我还有更多坏消息…… 【参考方案1】:

Firebase Query 模型中,您不能过滤不相等的值

但是您可以测试是否缺少任何值(本质上是:缺少属性)。以这个数据模型为例:


    child1: 
      "user": 
        "id": 1,
        "name": "puf"
      
    ,
    child2: 
      "user": 
        "id": 2,
        "name": "abe"
      
    ,
    child3: 
      "user": 
        "id": 3
      
    

我可以查询没有user/name 属性的孩子:

ref.orderByChild('user/name').equalTo(null)

这导致唯一没有名字的孩子:

孩子3

随意玩我的 jsbin 看看你能不能走得更远:http://jsbin.com/liyibo/edit?js,console

更新:我知道我以前回答过这个问题,但之前找不到。这是骗子:is it possible query data that are not equal to the specified condition?。看起来我有一个错误,因为显然我正在测试上面代码中是否缺少属性。

【讨论】:

谢谢,弗兰克!但通常在用户的情况下,我想过滤一个孩子*是否是由某个用户创建的。在这种情况下,id/name 永远不会为空 我知道。因此第一行粗体:无法过滤具有与“标记值”不同的值的节点。抱歉,我没有更好的消息。 谢谢,弗兰克!感谢您的及时答复。所以我想唯一的方法是获取客户端上的所有值并在那里过滤它(虽然有点昂贵的操作)。我希望这样的功能可以在新版本中实现:) @FrankvanPuffelen hi frank,有一个问题,当你说ref.orderByChild('child/name').equalTo(null)时,你的意思是child1的父节点命名为child 谢谢。它提供了更多信息。【参考方案2】:

我想我已经找到了解决方案,这更多的是应该如何设计数据库,实际上现在我理解了 Firebase 指南背后的意图

https://firebase.google.com/docs/database/android/structure-data

原创设计:


    child1: 
      "user": 
        "id": "id1",
        "name": "puf"
      
    ,
    child2: 
      "user": 
        "id": "id2",
        "name": "abe"
      
    ,
    child3: 
      "user": 
        "id": "id1"
        "name": "puf"
      
    

更新设计:

所以除了存储用户的id和name之外,我们还应该存储一个以id本身为key的节点,并将其标记为true


    child1: 
      "user": 
        "id": "id1",
        "name": "puf"
        "id1": true
      
    ,
    child2: 
      "user": 
        "id": "id2",
        "name": "abe"
        "id2": true
      
    ,
    child3: 
      "user": 
        "id": "id1"
        "name": "puf"
        "id1": true
      
    

使用更新的设计,如果我执行ref.orderByChild('user/id1').equalTo(true)

我会得到 Child1 和 Child 3 的输出

如果我执行ref.orderByChild('user/id1').equalTo(null)

我会得到 Child2 作为输出

【讨论】:

有趣的方法,存储的数据有点贵,但肯定有用 我正在使用 Firestore,我通过以下方式尝试了这种技术:ref => ref.where(`user.$userID`, '==', null) 在我的查询中但它不起作用......我实际上必须设置一个属性,等于用户 ID,为 null在我的数据中,以便在我的查询中得到结果。搜索继续排除 Firestore 查询中的数据... 问题/答案适用于 Firebase 实时数据库,而不是 Firestore。

以上是关于Firebase:查询以根据条件排除数据的主要内容,如果未能解决你的问题,请参考以下文章

Db2 SQL 根据大量数据选择排除行的行

根据多个筛选条件 - SQL访问排除记录

从 ArrayList 中的 Firebase 检索数据以获取图形

SQL 排除匹配所有多个条件的行

在 Swift 3 中包含字典的 Firebase 进程子快照

使用 nativescript-plugin-firebase 添加带有查询的事件侦听器