處理推薦系統的Firebase中的大量數據



Answers

Firebase NoSQL JSON結構的最佳實踐是“避免嵌套數據”,但是你說,你不想改變你的數據。 因此,對於您的情況,您可以將REST調用到Firebase的任何特定節點(您的每個電影的節點)。

解決方案1)您可以通過ThreadPoolExecutors創建一些固定數量的線程。 從每個工作線程,您可以執行HTTP(REST調用請求)如下。 根據您的設備性能和內存能力,您可以決定通過ThreadPoolExecutors處理多少個工作線程。 你可以有如下所示的代碼片段:

/* creates threads on demand */
    ThreadFactory threadFactory = Executors.defaultThreadFactory(); 

/* Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available */

    ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(10); /* you have 10 different worker threads */  

for(int i = 0; i<100; i++) { /* you can load first 100 movies */
/* you can use your 10 different threads to read first 10 movies */
threadPoolExecutor.execute(() -> {



        /* OkHttp Reqeust */
        /* urlStr can be something like "https://earthquakesenotifications.firebaseio.com/movies?print=pretty" */
                Request request = new Request.Builder().url(urlStr+"/i").build(); 

    /* Note: Firebase, by default, store index for every array. 
Since you are storing all your movies in movies JSON array, 
it would be easier, you read first (0) from the first worker thread, 
second (1) from the second worker thread and so on. */

                try {
                    Response response = new OkHttpClient().newCall(request).execute(); 
    /* OkHttpClient is HTTP client to request */
                    String str = response.body().string();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return myStr;
            });
            }
                threadPoolExecutor.shutdown();

解決方案2)解決方案1不基於Listener-Observer模式。 實際上,Firebase有PUSH技術。 也就是說,只要Firebase NoSQL JSON中的某個特定節點發生更改,具有JSON特定節點的連接偵聽器的相應客戶端將通過onDataChange(DataSnapshot dataSnapshot) { }獲取新數據。 為此,您可以像下面那樣創建一個DatabaseReferences數組:

      Iterable<DataSnapshot> databaseReferenceList = FirebaseDatabase.getInstance().getReference().getRoot().child("movies").getChildren();

for(DataSnapshot o : databaseReferenceList) { 
 @Override
            public void onDataChange(DataSnapshot o) {



      /* show your ith movie in ListView. But even you use RecyclerView, showing each Movie in your RecyclerView's item is still show. */
/* so you can store movie in Movies ArrayList. When everything completes, then you can update RecyclerView */

                }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
}
Question

我正在構建推薦系統,我使用Firebase存儲和檢索有關電影用戶偏好的數據

每部電影可以有幾個屬性,數據如下所示:

{ 
    "titanic": 
    {"1997": 1, "english": 1, "dicaprio": 1,    "romance": 1, "drama": 1 }, 
    "inception": 
    { "2010": 1, "english": 1, "dicaprio": 1, "adventure": 1, "scifi": 1}
...
}

為了提出建議,我的算法需要輸入所有數據(電影),並與用戶配置文件進行匹配。

但是,在生產模式下,我需要檢索超過10,000個電影。 雖然算法可以相對較快地處理這個問題,但是從Firebase加載這些數據需要花費很多時間。

我檢索數據如下:

firebase.database().ref(moviesRef).on('value', function(snapshot) {
    // snapshot.val();
}, function(error){
    console.log(error)
});

我在那裡想知道如果你有任何想法如何加快速度? 有沒有解決這個問題的插件或技術?

我知道,非規範化可以幫助分割數據,但問題是我需要所有電影和所有相應的屬性。