48

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

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

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

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

因此,对于我的情况,例如,如果用户键入“cho”,我需要同时带上“chocolate”和“chochocho”作为结果。我考虑将所有数据放在“产品”块下,然后在客户端进行查询,但这可能需要大量内存用于大型数据库。那么,我该如何执行 sql LIKE 操作呢?

谢谢

4

5 回答 5

31

更新:随着 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>

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

于 2014-03-20T03:26:50.677 回答
19

我相信你可以做到:

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

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

资源

于 2017-08-21T03:55:06.423 回答
1

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

虽然我喜欢并推荐弹性搜索项目的成熟度,但同样可以在没有另一台服务器的情况下完成,只使用 firebase 数据库。这就是我的意思:(https://github.com/metashema/oxyzen

对于索引部分基本上是功能:

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

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

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

于 2016-06-09T23:32:44.723 回答
1

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

let node = await db.ref('yourPath').orderByChild('yourKey').startAt('!').endAt('SUBSTRING\uf8ff').once('value');
于 2019-04-11T11:37:15.197 回答
-3

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

select * from StoreAds where University Like %ps%;

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

于 2020-02-03T22:11:53.843 回答