搜索是我当前应用程序中最重要的部分之一。它需要感觉像一个快速,准确,全球搜索。该应用基于Firebase,我发现Firebase的equalTo()/ startAt()组合在这方面相当缺乏。
我想要实现的目标:
我已经做了什么
我没有使用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) {
}
});
我猜测需要做的是每个匹配需要得到searchResults
的分数,在我们完成循环之后,需要按照这个分数对ArrayList进行排序。我的主要问题归结为如何在考虑上述标准的情况下获得最佳分数。任何图书馆或代码样本都将非常受欢迎。
提前致谢。
答案 0 :(得分:2)
在尝试自己的得分和谷歌搜索失败后,我找到了FuzzyWuzzy。这个相当不错的库使用levenshtein,但具有extractTop()
和extractAll()
功能。它实际上是一种部分模糊搜索,非常适合这种情况。
库只是在Strings中搜索,但您可以通过创建仅字符串数组和引用数组来解决这个问题。