我有 Big Data 有近100万条记录甚至更多,第一次查询需要很长时间,而且大部分时间都是这样.

我的规则是:

{
  "rules": {
    "iBkH2321":{
      "$uid":{
        ".read": "false",
          ".write": "true"    
      }
    },
      "Contacts":{
            ".indexOn": ["mobile","name","android_id"],
           ".read":"root.child('iBkH2321').child(auth.uid).val() == true",
          ".write":"root.child('iBkH2321').child(auth.uid).val() == true",
      },
    "AppVersion":{
      ".read": "true",
          ".write": "false",
            ".indexOn":["VersionNumber"]
    }
  }
}

这样的数据:

 

{
  "contacts" : {
    "-Moj9LK306LUDCXIbypG" : {
         "-Moj9LK5rgNYVcD1PJ2S" : {
          "android_id" : "312e62167b076ce1",
          "mobile" : "770966855",
          "name" : "عبدالله سيلان / فرع اب الشركة"
          },
         "-Moj9LKEZgZqu8tyW-4c" : {
          "android_id" : "312e62167b076ce1",
          "mobile" : "711237507",
          "name" : "عبد الملك عمر / الهلال للصرافة تعز"
         },
         "-Moj9LKFmA0E6jJMuWfD" : {
          "android_id" : "312e62167b076ce1",
          "mobile" : "711290007",
          "name" : "احمد هاشم /ايتي عدن للصرافة"
         },
         .
         .
         .
    "-MopGM8c8Fosxb0WKJpx" : {
         .
         . 
    }
    .
    .
  "iBkHop2321" : {
    "026Z0V8ad8MnJtnfn9qt6atgMWS2" : true,
    "0CDZ0V8aAxMnJtnre9qt6atgZiw2" : true,
         .
         .
         .
         . 
     }

这是我的密码:

private  DatabaseReference myRef ;
.
.
.
final FirebaseDatabase database = FirebaseDatabase.getInstance();
        myRef = database.getReference("Contacts");
auth = FirebaseAuth.getInstance();
.
.
.

   private  void TestShearch(String number){
        AtomicBoolean getResult = new AtomicBoolean(false);
        ArrayList<Contacts> arrayList = new ArrayList<>();
        ArrayContacts arrayContacts = new ArrayContacts(context, arrayList);
        listView.setAdapter(arrayContacts);
        Query query = myRef.orderByChild("mobile").equalTo(number).limitToLast(30);
        ValueEventListener valueEventListener = new ValueEventListener() {
           @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if(isAdded() && activity != null) {
                    arrayList.clear();
                        getResult.set(true);
                        for (DataSnapshot ds : snapshot.getChildren()) {
                            Contacts con = ds.getValue(Contacts.class);
                            arrayList.add(con);
                            assert con != null;
                        }
                        arrayContacts.notifyDataSetChanged();
                        listView.setAdapter(arrayContacts);
                    } else {
                        getResult.set(false);
                        Toast.makeText(context, "لا توجد بيانات لهذا الرقم حالياً", Toast.LENGTH_LONG).show();
                    }
                    progressBar.setVisibility(View.GONE);
                    btn_search.setVisibility(View.VISIBLE);
                    myRef.removeEventListener(this);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                //do somthing here
            }
        };
 query.addListenerForSingleValueEvent(valueEventListener);
}

注意:我在onStart()中使用身份验证:

@Override
    protected void onStart() {
        super.onStart();
        FirebaseUser currentUser = mAuth.getCurrentUser();
        updateUI(currentUser);
    }

private void updateUI(FirebaseUser currentUser) {
        if(currentUser == null){
            mAuth.signInAnonymously().addOnCompleteListener(this, new         OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if(task.isSuccessful()){

                        FirebaseUser user = mAuth.getCurrentUser();
                        updateUI(user);
                        myRef2.child(Objects.requireNonNull(mAuth.getUid())).setValue(true);
                        Log.d("userAuth11", "signInAnonymously:parent success");

                    } else{
                        Log.d("userAuth11", "signInAnonymously:parent failed");
                        updateUI(null);
                    }
                }
            });

        }

当我启动应用程序时,查询需要30-60秒以上,之后变得比旧的查询更快!

你能帮帮我吗? 谢谢.

我认为问题出在我查询的数据的大小上,因为数据的大小大约是2 GB?

推荐答案

我的 Big Data 有近100万条记录,甚至更多

这可能就是问题所在.FireBase实时数据库将其索引保存在内存中,以便快速访问,但这确实意味着在性能下降之前,它在索引中可以容纳的项目数是有限制的.

您需要考虑更改数据模型以更好地满足您的需求.在使用NoSQL数据库时,重新建模数据以适应您的用例是非常常见的.

例如,如果要按联系人的电话号码访问联系人,请考虑创建一个精确存储该数据的额外数据 struct :

contacts_by_mobile: {
  "770966855": {
    "-Moj9LK306LUDCXIbypG": true
  },
  "711237507": {
    "-Moj9LK306LUDCXIbypG": true
  },
  "711290007": {
    "-Moj9LK306LUDCXIbypG": true
  }
  ...
}

您可以使用它来查找联系人键,而不需要查询整个contacts个列表,然后在不查询的情况下逐个查找单个联系人.有很多方法可以做到这一点,几乎任何方法都可以满足您的用例.

另请参阅:

Java相关问答推荐

如何在多个设备上同时运行Android Studio的项目?

gitlab ci不会运行我的脚本,因为它需要数据库连接'

无法找到符号错误—Java—封装

我无法将附件发送到NetBeans之外

RESTful框架类字段是安全的还是不安全的

如何在EXCEL单元格中添加形状和文本

SpringBoot Kafka自动配置-适用于SASL_PLAYTEXT的SSLBundle 包,带SCRAM-SHA-512

用OSQL创建索引

如何从日志(log)行中删除包名称?

如何使用log4j2(Json)记录由";异常引起的所有";?

根本不显示JavaFX阿拉伯字母

从映射列表中检索所有键

如何获得凌空cookies ,并设置它在下一个请求- android

STREAMS减少部分结果的问题

有没有办法知道在合并中执行了什么操作?

处理4.3问题:javax.xml.ind包不存在(&Q;).您可能在学习GitHub教程时遗漏了库.&Q

在Java Spring JPA中插入包含对其他实体的引用的列

在Java中使用StorageReference将数据从Firebase存储添加到数组列表

为什么没有加载java.se模块?

始终使用Spring Boot连接mongodb上的测试数据库