web-dev-qa-db-ja.com

firebaseでSQL「LIKE」操作を実行する方法

データストレージにfirebaseを使用しています。データ構造は次のとおりです。

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

このデータに対してオートコンプリート操作を実行したいので、通常、次のようなクエリを作成します。

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

したがって、たとえば、私の状況では、ユーザーが「cho」と入力した場合、結果として「chocolate」と「chochocho」の両方を取得する必要があります。すべてのデータを「製品」ブロックの下に置き、クライアントでクエリを実行することを考えましたが、これには大きなデータベースのために大量のメモリが必要になる場合があります。だから、どのようにSQL LIKE操作を実行できますか?

ありがとう

40
yrazlik

更新:Firebase用Cloud Functionsのリリースでは、これを行うための別のエレガントな方法があります 関数を介してFirebaseをAlgoliaにリンクするここでのトレードオフは、Functions/Algoliaのメンテナンスがほとんど不要であることですが、おそらくNodeでのロールオーバーオーナーよりもコストが高くなります。

現在、Firebaseにはコンテンツ検索はありません。属性による検索など、より一般的な検索シナリオの多くは、APIの拡張が進むにつれてFirebaseに組み込まれます。

それまでの間、あなた自身を成長させることは確かに可能です。ただし、検索は広大なトピックであり(リアルタイムのデータストアを膨大に作成することを考えてください)、非常に過小評価されており、アプリケーションの重要な機能です。 。したがって、通常、スケーラブルなサードパーティツールを使用して、インデックス作成、検索、タグ/パターンマッチング、ファジーロジック、加重ランキングなどを処理する方が簡単です。

Firebaseブログの特徴は ElasticSearchによるインデックス作成に関するブログ投稿 です。これは、Firebaseバックエンドに非常に強力な高速検索エンジンを統合するための簡単なアプローチの概要を示しています。

基本的には、2つのステップで行われます。データを監視し、インデックスを作成します。

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>

ここに例と、統合を簡素化するサードパーティのライブラリがあります

25
Kato

私はあなたができると信じています:

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

これにより、名前がchoで始まるvalが見つかります。

ソース

11
Ced

FirebaseでのSQL「LIKE」操作が可能

let node = await db.ref('yourPath').orderByChild('yourKey').startAt('!').endAt('SUBSTRING\uf8ff').once('value');
3
Mili Shah

エラスティック検索ソリューションは基本的にバインドしてセットdelを追加し、テキスト検索を実行できるget byを提供します。次に、内容をmongodbに保存します。

私はプロジェクトの成熟度を弾力的に検索することを好み、推奨していますが、同じことは別のサーバーなしで、firebaseデータベースのみを使用して行うことができます。それが私が言っていることです:( https://github.com/metaschema/oxyzen

インデックス部分の基本的な機能:

  1. JSONはドキュメントを文字列化します。
  2. すべてのプロパティ名とJSONを削除して、データのみを残します(正規表現)。
  3. xmlまたはhtmlが存在する場合に純粋なテキストのみを残すために、すべてのxmlタグ(したがってhtml)および属性(古いガイダンス「XML属性にデータを含めることはできません」を忘れないでください)を削除します。
  4. すべての特殊文字を削除し、スペースで置き換えます(正規表現)
  5. 複数のスペースのすべてのインスタンスを1つのスペースに置き換えます(正規表現)
  6. スペースとサイクルに分割します:
  7. 各Wordに対して、dbのインデックス構造のドキュメントに参照を追加します。基本的に、「ref/inthedatabase/dockey」のエスケープバージョンで名前の付いた子を持つ単語で名前の付いた子が含まれます。
  8. その後、通常のfirebaseアプリケーションが行うようにドキュメントを挿入します

oxyzenの実装では、ドキュメントの後続の更新によりインデックスが実際に読み取られて更新され、一致しない単語が削除され、新しい単語が追加されます。

その後の単語の検索では、単語childのドキュメントを直接検索できます。複数の単語の検索は、ヒットを使用して実装されます

1
user3191409