如何在firebase上执行sql“LIKE”操作?

IT技术 javascript firebase firebase-realtime-database
2021-01-26 22:08:12

我正在使用 firebase 进行数据存储。数据结构是这样的:

products:{
   product1:{
      name:"chocolate",
   }
   product2:{
      name:"chochocho",
   }
}

我想对此数据执行自动完成操作,通常我会像这样编写查询:

"select name from PRODUCTS where productname LIKE '%" + keyword + "%'";

因此,对于我的情况,例如,如果用户输入“cho”,我需要同时携带“chocolate”和“chochocho”作为结果。我想过将所有数据都放在“products”块下,然后在客户端进行查询,但这对于大数据库来说可能需要大量内存。那么,我如何执行 sql LIKE 操作?

谢谢

5个回答

更新:随着 Cloud Functions for Firebase 的发布,还有另一种优雅的方法可以通过 Functions 将 Firebase 链接到 Algolia这里的权衡是 Functions/Algolia 几乎是零维护,但可能比在 Node.js 中自己动手的成本更高。

目前 Firebase 中没有内容搜索。随着 API 的不断扩展,许多更常见的搜索场景(例如按属性搜索)将被纳入 Firebase。

与此同时,当然可以自己种植。然而,搜索是一个庞大的主题(想想创建一个庞大的实时数据存储),被大大低估了,并且是您的应用程序的一个关键功能——不是您想要的临时功能,甚至不是依赖 Firebase 之类的人代表您提供. 因此,使用可扩展的第三方工具来处理索引、搜索、标签/模式匹配、模糊逻辑、加权排名等通常更简单。

Firebase 博客中有一篇关于使用 ElasticSearch 编制索引博客文章,其中概述了将快速但极其强大的搜索引擎集成到 Firebase 后端的简单方法。

基本上,它分两步完成。监控数据并建立索引:

var Firebase = require('firebase');
var ElasticClient = require('elasticsearchclient')

// initialize our ElasticSearch API
var client = new ElasticClient({ host: 'localhost', port: 9200 });

// listen for changes to Firebase data
var fb = new Firebase('<INSTANCE>.firebaseio.com/widgets');
fb.on('child_added',   createOrUpdateIndex);
fb.on('child_changed', createOrUpdateIndex);
fb.on('child_removed', removeIndex);

function createOrUpdateIndex(snap) {
   client.index(this.index, this.type, snap.val(), snap.name())
     .on('data', function(data) { console.log('indexed ', snap.name()); })
     .on('error', function(err) { /* handle errors */ });
}

function removeIndex(snap) {
   client.deleteDocument(this.index, this.type, snap.name(), function(error, data) {
      if( error ) console.error('failed to delete', snap.name(), error);
      else console.log('deleted', snap.name());
   });
}

想要搜索时查询索引:

<script src="elastic.min.js"></script>
 <script src="elastic-jquery-client.min.js"></script>
 <script>
    ejs.client = ejs.jQueryClient('http://localhost:9200');
    client.search({
      index: 'firebase',
      type: 'widget',
      body: ejs.Request().query(ejs.MatchQuery('title', 'foo'))
    }, function (error, response) {
       // handle response
    });
 </script>

这里有一个示例和一个用于简化集成的第三方库。

啊谢谢你,但我实际上在我的 android 应用程序中使用了 firebase,我对 javascript 知之甚少。你能给我一个链接或一个像这个用java代码编写的javascript示例的小例子吗?我现在也会试着去理解那个 javascript 代码 :) 谢谢
2021-03-12 22:08:12
这在 2016 年仍然相关吗?
2021-03-22 22:08:12
概念相关。API 调用的语法略有不同。
2021-03-23 22:08:12
嗨 Kato,我在这里发布了一个关于使用新 Firebase 进行手电筒设置的问题,希望您能提供一些知识!我真的很感激,谢谢!stackoverflow.com/questions/38276209/...
2021-03-31 22:08:12
遗憾的是,您必须升级到 Blaze 计划才能在 Algolia 中使用 Firebase Cloud Functions
2021-04-05 22:08:12

我相信你可以做到:

admin
.database()
.ref('/vals')
.orderByChild('name')
.startAt('cho')
.endAt("cho\uf8ff")
.once('value')
.then(c => res.send(c.val()));

这将找到名称以 cho 开头的 val。

来源

这帮助我构建了一个小型搜索功能。我为每个单词创建了一个索引,将每个单词链接到相关项目。然后,在搜索时,我计算每个项目的点击次数。
2021-03-11 22:08:12
@Ced 有没有办法获得包含cho 的名称,而不仅仅是以它们开头(qwerty cho,ab cho ba)?
2021-03-20 22:08:12
根据我的理解, startAt() 和 endAt() 用于限制数据库中两个特定对象之间的结果 - 而不是查询字符串的内容。
2021-04-03 22:08:12
@Heisenbug 它有效,源视频来自谷歌本身。
2021-04-03 22:08:12
这有效,谢谢!希望 Firebase 开发人员在管道中提供更“本机”的解决方案。
2021-04-07 22:08:12

elasticsearch解决方案基本上绑定到添加 set del 并提供一个 get by ,您可以完成文本搜索。然后它将内容保存在 mongodb 中。

虽然我喜欢并推荐elasticsearch项目的成熟度,但同样可以在没有其他服务器的情况下完成,仅使用 firebase 数据库。这就是我的意思:(https://github.com/metaschema/oxyzen

索引部分的基本功能是:

  1. JSON 将文档字符串化。
  2. 删除所有属性名称和 JSON 以仅保留数据(正则表达式)。
  3. 删除所有 xml 标记(因此也是 html)和属性(请记住旧指南,“数据不应在 xml 属性中”),如果存在 xml 或 html,则仅保留纯文本。
  4. 删除所有特殊字符并用空格替换(正则表达式)
  5. 用一个空格替换多个空格的所有实例(正则表达式)
  6. 拆分为空间和循环:
  7. 对于每个单词,在您的数据库中的某个索引结构中向文档添加 refs 基本上包含以单词命名的子项,其中以“ref/inthedatabase/dockey”的转义版本命名的子项
  8. 然后像普通的 firebase 应用程序一样插入文档

在 oxyzen 实现中,文档的后续更新实际上读取索引并更新它,删除不再匹配的单词,并添加新的单词。

后续的words搜索可以直接在child中找到文档。使用命中实现多词搜索

可以在 firebase 上执行 SQL“LIKE”操作

let node = await db.ref('yourPath').orderByChild('yourKey').startAt('!').endAt('SUBSTRING\uf8ff').once('value');
如果数据库很大,请不要使用此建议。执行此请求后,我的数据库停止工作,并且在大约 5 分钟内没有从不同设备发送响应。也许这个问题与 firebase 数据库逻辑有关。
2021-04-02 22:08:12

这个查询对我有用,它看起来像 MySQL 中的以下语句

select * from StoreAds where University Like %ps%;

query = database.getReference().child("StoreAds").orderByChild("University").startAt("ps").endAt("\uf8ff");

这不能正常工作,运行更多的测试,你会看到。
2021-03-27 22:08:12