如何在Firebase数据库中进行简单的字符串搜索?

时间:2016-07-27 16:50:39

标签: android firebase firebase-realtime-database

我想在我的应用中创建一个简单的搜索,但在互联网上找不到任何关于它的东西,这比2014年更新。必须有更好的方法。有startAt和endAt函数,但它们没有按预期工作,并且区分大小写。你们是如何解决这个问题的? 2016年该功能如何仍然不存在?

9 个答案:

答案 0 :(得分:89)

在我的情况下,我能够通过以下方式部分实现SQL LIKE:

databaseReference.orderByChild('_searchLastName')
                 .startAt(queryText)
                 .endAt(queryText+"\uf8ff")

查询中使用的字符\uf8ff是Unicode范围内的一个非常高的代码点(它是私有使用区[PUA]代码)。因为它是Unicode之后的大多数常规字符,所以查询匹配以queryText开头的所有值。

通过这种方式,通过“Fre”搜索,我可以从数据库中获取{Fred,Freddy,Frey“作为_searchLastName属性值的记录。

答案 1 :(得分:3)

创建两个String变量

    searchInputToLower = inputText.getText().toString().toLowerCase();

    searchInputTOUpper = inputText.getText().toString().toUpperCase();

然后在查询中将其设置为:

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Products");//Your firebase node you want to search inside..

    FirebaseRecyclerOptions<Products> options =
            new FirebaseRecyclerOptions.Builder<Products>()//the Products is a class that get and set Strings from Firebase Database.
            .setQuery(reference.orderByChild("name").startAt(searchInputUpper).endAt(searchInputLower + "\uf8ff"),Products.class)
            .build();

“名称”是产品主节点内的节点。

.startAt(searchInputUpper)和.endAt(searchInputLower +“ \ uf8ff”)进行搜索,其中包含您所输入的inputText.getText()中键入的所有字符。

答案 2 :(得分:1)

Firebase没有内置搜索功能的优秀SQL。您可以按值/键排序,也可以等于

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

您可以在上面的链接中找到示例。这是firebase的最新文档。

如果您正在寻找类似搜索的SQL。然后看一下弹性搜索。但这会增加复杂性,因为您需要一个平台来实现它。为此我可以推荐Heroku或者GoogleCloudServers

这是一篇关于使用弹性搜索进行高级搜索的博文 https://firebase.googleblog.com/2014/01/queries-part-2-advanced-searches-with.html

答案 3 :(得分:1)

这个问题可能已经过时了但是有一种记录如何实现这种方式的方法,实现起来很简单。 Quoted

  

要启用Cloud Firestore数据的全文搜索,请使用Algolia等第三方搜索服务。考虑一个笔记记录应用程序,其中每个笔记都是一个文档:

Algolia将成为您firebase functions的一部分,并会执行您想要的所有搜索。

// Update the search index every time a blog post is written.
exports.onNoteCreated = functions.firestore.document('notes/{noteId}').onCreate(event => {
      // Get the note document
      const note = event.data.data();

      // Add an 'objectID' field which Algolia requires
      note.objectID = event.params.noteId;

      // Write to the algolia index
      const index = client.initIndex(ALGOLIA_INDEX_NAME);
      return index.saveObject(note);
});

要实施搜索,最好的方法是使用instant search - android

示例搜索图片:GIF

答案 4 :(得分:1)

您正在寻找的功能称为全文搜索,这是大多数数据库(包括 Firebase)不提供的现成功能,因为它需要以针对文本优化的格式存储数据搜索(与针对过滤进行了优化)- 这是两个不同的问题集,具有不同的权衡。

因此,您必须将单独的全文搜索引擎与 Firebase 结合使用才能做到这一点,尤其是在您需要分面、错字容忍、商品推销等功能时。

全文搜索引擎有几个选项:

  • Algolia 易于启动和运行,但很快就会变得昂贵
  • ElasticSearch 的学习曲线陡峭但非常灵活
  • Typesense 旨在成为 Algolia 的开源替代品。

答案 5 :(得分:0)

我不知道这种方法的确定性,但在android上使用firebase版本10.2.6,我可以这样做:

firebaseDatabase.getReference("parent")
                            .orderByChild("childNode")
                            .startAt("[a-zA-Z0-9]*")
                            .endAt(searchString)

有时似乎运作良好

答案 6 :(得分:0)

最后加入SO只是为了回答这个问题。 对于任何来自python firestore.client或来自python firestore.client的用户,这里的解决方案似乎对我有用。 它基于接受的答案的概念,但是通过客户端而不是db.reference()并与user12750908中的answer混合。

from firebase_admin import firestore 
users = db.collection("users")\
        .order_by("last_name")\
        .where("last_name", ">=", last_name.upper())\
        .where("last_name", "<=", last_name.lower() + "\uf8ff")\
        .stream()

它适用于我所做的简单测试,但是如果以后遇到问题,我将更新答案。提醒一下,这类似于

LIKE search%

不是

LIKE %search%.

编辑1 我没有看到该问题的任何标签,但是title属性提到了Android,因此这不一定可以直接回答问题,但是如果您有python API,则应该可以。不幸的是,我不确定Android版本中是否存在等效的客户端/数据库分离,如Python的Firebase Admin中一样。我不想删除答案,因为在搜索类似答案时没有看到任何关于firestore客户端的答案,并希望它能帮助其他人绊脚石。

编辑09-03-2020 。大多数时候,我似乎都没有问题,但是当我将其应用于另一个项目时,却得到了意想不到的结果。长话短说,您可能需要复制保存比较数据的方式。例如,您可能需要一个字段以所有大写形式保存last_name,另一个字段以所有小写形式保存它,然后更改第一个where子句以比较last_name_upper和第二个以比较last_name_lowercase。到目前为止,在我的第二个项目中,这似乎产生了更准确的结果,因此,如果先前的答案不能很好地起作用,您可能要尝试一下

编辑09-07-2020 从2020年9月3日开始的先前编辑部分准确。在匆忙思考的过程中,我已经完全解决了,我完全忘记了firebase不允许您在不同的字段中使用<,>,<=,> =。您可能需要执行两个查询并合并它们,但是您可能仍在阅读比您预期更多的文档。用适当的搜索词对较高或较低版本进行比较,似乎可以得到原始答案所期望的原始结果。例如:

.orderBy("last_name_upper")
    .where("last_name_upper", ">=", this.searchForm.text.toUpperCase())
    .where("last_name_upper", "<=", this.searchForm.text.toUpperCase() + "\uf8ff")

答案 7 :(得分:-1)

我使用了我的案例:

var query = 'text'
databaseReference.orderByChild('search_name')
             .startAt(`%${query}%`)
             .endAt(query+"\uf8ff")
             .once("value")

通过这种方式,通过&#34; test&#34;我可以获得记录&#34;测试1,比赛,一个测试&#34;作为&#39;搜索&#39;中的价值来自数据库的财产。

答案 8 :(得分:-2)

要回答一些人的疑问,如何搜索“ fri”并显示“ Frid”,“ Fries”,“ Friii”。您可以通过在.toUpperCase()方法内添加startAt和在.toLowerCase()方法内添加endAt来轻松做到这一点

in this image i am searching for a username base on username key in by firebase database