Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Firebase高级模糊搜索,采用levenshtein排序和逐字搜索_Android_Firebase_Firebase Realtime Database_Levenshtein Distance_Fuzzy Search - Fatal编程技术网

Android Firebase高级模糊搜索,采用levenshtein排序和逐字搜索

Android Firebase高级模糊搜索,采用levenshtein排序和逐字搜索,android,firebase,firebase-realtime-database,levenshtein-distance,fuzzy-search,Android,Firebase,Firebase Realtime Database,Levenshtein Distance,Fuzzy Search,搜索是我当前应用程序中最重要的部分之一。它需要感觉像一个快速、准确的全球搜索。该应用程序基于Firebase,我发现Firebase的equalTo()/startAt()组合在这方面相当缺乏 我想要实现的目标: 结果按相关性排序 逐字匹配(soöpime应产生上述结果) 搜索多个属性(因此põhjala pime应产生上述结果) 模糊搜索(levenshtein?)-pojala应该匹配Põhjala 我已经做过的 我没有使用equalTo(),而是下载整个分支(例如啤酒),并在其中循环

搜索是我当前应用程序中最重要的部分之一。它需要感觉像一个快速、准确的全球搜索。该应用程序基于Firebase,我发现Firebase的equalTo()/startAt()组合在这方面相当缺乏

我想要实现的目标:

  • 结果按相关性排序
  • 逐字匹配(soöpime应产生上述结果)
  • 搜索多个属性(因此põhjala pime应产生上述结果)
  • 模糊搜索(levenshtein?)-pojala应该匹配Põhjala
我已经做过的

我没有使用equalTo(),而是下载整个分支(例如啤酒),并在其中循环,执行我自己的
contains()
。这是可行的,而且速度相当快。然而,它缺少我提到的所有东西。这是当前的代码

           final ArrayList<SearchBeerAdapter.BeerBrewery> searchResults = new ArrayList<>();
            FirebaseUtil.getBeersRef().orderByChild("name").addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(final DataSnapshot ogDS) {
                    int childCounter = 0;
                    for (DataSnapshot ds: ogDS.getChildren()){
                        childCounter++;
                        if (resultCounter[0] < 5) {
                            final Beer beer = ds.getValue(Beer.class);
                            final String beerId = ds.getKey();

                            // Limit to five results and remove listener
                            final int finalChildCounter = childCounter;
                            FirebaseUtil.getBreweriesRef().child(beer.getBreweryId()).addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(DataSnapshot dataSnapshot) {
                                    Brewery brewery = dataSnapshot.getValue(Brewery.class);
                                    if (beer.getFullName().toLowerCase().contains(query.toLowerCase()) || brewery.getName().toLowerCase().contains(query.toLowerCase())) {
                                        resultCounter[0] = resultCounter[0] + 1;
                                        if (resultCounter[0] < 5) {
                                            searchResults.add(new SearchBeerAdapter.BeerBrewery(beer, brewery, beerId));
                                        }
                                    }

                                    // Initialize the adapter once we've hit the end of our results
                                    if (finalChildCounter == ogDS.getChildrenCount()){
                                        SearchBeerAdapter sa = new SearchBeerAdapter(searchResults,glide);
                                        rv.setAdapter(sa);
                                    }

                                }

                                @Override
                                public void onCancelled(DatabaseError databaseError) {

                                }
                            });
                        }

                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
final ArrayList searchResults=new ArrayList();
FirebaseUtil.getBeersRef().orderByChild(“名称”).addValueEventListener(新的ValueEventListener()){
@凌驾
公共无效onDataChange(最终数据快照ogDS){
int childCounter=0;
对于(DataSnapshot ds:ogDS.getChildren()){
childCounter++;
如果(结果计数器[0]<5){
最终啤酒=ds.getValue(Beer.class);
最后一个字符串beerId=ds.getKey();
//限制为五个结果并删除侦听器
final int finalChildCounter=子计数器;
FirebaseUtil.getBreweriesRef().child(beer.getBreweryId()).addListenerForSingleValueEvent(新值EventListener()){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
Brewery Brewery=dataSnapshot.getValue(Brewery.class);
if(beer.getFullName().toLowerCase().contains(query.toLowerCase())| | brewery.getName().toLowerCase().contains(query.toLowerCase()){
结果计数器[0]=结果计数器[0]+1;
如果(结果计数器[0]<5){
searchResults.add(新的SearchBeerAdapter.BeerBrewery(啤酒,啤酒厂,啤酒厂));
}
}
//在结果结束后初始化适配器
如果(finalChildCounter==ogDS.getChildrenCount()){
SearchBeerAdapter sa=新的SearchBeerAdapter(搜索结果,滑动);
rv.设置适配器(sa);
}
}
@凌驾
已取消的公共void(DatabaseError DatabaseError){
}
});
}
}
}
@凌驾
已取消的公共void(DatabaseError DatabaseError){
}
});
我猜需要做的是,每个匹配都需要在
搜索结果中获得一个分数,在我们完成循环之后,ArrayList需要根据这个分数排序。我的主要问题是,考虑到上述标准,如何获得最佳分数。非常欢迎使用任何库或代码示例


提前谢谢。

在尝试自己打分和谷歌搜索失败后,我发现了很多。这个相当不错的库使用了levenshtein,但是有一个
extractTop()
extractAll()
功能。它实际上是一个局部模糊搜索,非常适合这种情况


该库只在字符串中搜索,但您可以通过创建仅字符串数组和引用数组来解决这一问题

您不应该直接查询firebase数据库进行搜索,它不是为此而构建的。还有其他工具可以帮助你解决这个问题,你可以查看algolia.com,我之前提到过它是一个潜在的解决方案。嗯,这对我来说不是最好的解决方案。从长远来看,我看到了一家专门的搜索提供商的吸引力,但从短期来看,这意味着将我的数据同步到第二方,可能需要向第二方付费,或者有一个面向用户的徽标,这对他们来说毫无意义。我将保存此链接,但目前我的应用程序对于此链接来说太小了。此外,我并没有在Firebase中搜索。我只是查询然后在结果数组中搜索。