0

Lucene は重すぎると思うので使いたくありません。

これを実装する簡単な方法はありますか (何百万ものデータ)?

4

3 に答える 3

0

パフォーマンスについて心配したくない場合は、Amazon Web Services の新しい CloudSearch サービスを検討することをお勧めします。高速で、ニーズの拡大に合わせて拡張できます。また、何百万ものドキュメントを問題なく処理でき、ワイルドカード検索をサポートしています (例: quo* は Quora を取得します)。

ここでチェックしてください

于 2012-09-23T15:19:01.630 に答える
0

まず、オートコンプリートの場合、高速に表示するものが必要な場合は、100 ミリ秒以内にユーザーに応答を返すことを目指す必要があります。それがあなたの最初の関心事です。それができない設定は、おそらくユーザーにとって十分ではありません。Firebug を使用した Firefox での私自身のテストでは、Google のオートコンプリートは約 50 ミリ秒で返され、Quora は約 65 ミリ秒で返されました。

たとえば、参照してください

http://stackoverflow.com/questions/536300/what-is-the-shortest-perceivable-application-response-delay

どうやら、Quoraは全文検索ではなく接頭辞一致を使用しているため、高速になります。多くの場合、これで十分ですが、あいまい一致などを使用したスペルミスなどは処理されません。Redis などのインメモリ データ ストアを試してください。詳細は次の場所で確認できます。

http://charlesleifer.com/blog/powerful-autocomplete-with-redis-in-under-200-lines-of-python/

CloudSearch (Firebug で測定したエンドポイントから直接フェッチするブラウザーで 95 ~ 125 ミリ秒、および PHP で cURL を介してエンドポイントにアクセスする場合に + 20 ~ 30 ミリ秒長くなる) を、私が引用した Google と Quora の低レイテンシーまで下げることができませんでした。検索クエリのシンプルさ。Elasticsearch クラスターは少し高速です。これらのステートメントは明らかにユースケースに依存しており、おそらくうまく一般化することはできませんが、考慮すべきことがあります。

于 2013-09-11T04:21:45.383 に答える
0

明らかに、これは Quora や Google で確実に機能する方法ではありません。私はどちらでも働く喜びがなかったからです。

最初に取得するのは検索語のリストです。これがどのように行われるかを知りたくないと思いますが、実際にはあらゆる種類のものに依存しますが、基本的にはselect distinct title from pages(ウィキペディアのオートコンプリートの場合) または、Google の場合はもっと高度なものです。

次の手順も大まかに言えば非常に単純です。ユーザーが検索ボックスにselect title from titles where title like 'Qu%'入力した場合にクエリを実行する必要があります。Quタイトルのリストは、ある種の Ajax リクエストへの応答として、おそらく JSON などの形式でブラウザに返されます。そして、できるだけ早くそれを行う必要があります-それが困難になるところです.

彼らはどうやってそれをそんなに早くするのですか?心に留めておくべきことがおそらく4つあります。

  1. リクエストを処理するマシンがたくさんあります。Google のオートコンプリートはデフォルトでオンになっており、(ほぼ?) すべての言語で機能することに注意してください。これは、オートコンプリート インデックスに対する多くの検索です。Web インデックス自体に反対するよりもはるかに多くのことがあります。Web 検索リクエストごとに、Google はおそらく 3 つまたは 4 つのオートコンプリート リクエストを処理するでしょう。
  2. 彼らはおそらく記憶の中でそれをやっています。Google は Web インデックスをメモリに保存することで既に知られているため、Google もこれと同じことを行っていると予想されます。
  3. 専門的なソフトウェア (ここが本当に興味深いところです)。従来のデータベースや NoSQL データベースはこれを迅速に行うことができますが、大手企業は、オートコンプリートの提案を提供することだけを目的とした特殊なコードで実際にこれを行っていると思います。上記の SQL ステートメントは、必要となる論理的な要求を示すためだけのものです。おそらく、接尾辞ツリー、基数ツリーなど、ある種の特殊なツリーを見ていると思います。
  4. シャーディング。データの量とリクエストを実行するマシンの数に対処するには、シャードする必要があります。これにより、すべてのマシンの特定のサブセットが、1 つ以上の文字で始まるプロセス リクエスト リクエストのみを含むようになります。たとえば、特定の文字または 2 文字で始まる検索を処理する X マシンのグループです。これは、より多くのマシンを使用できることを意味しますが、それぞれがインデックス全体を処理する必要はありません。特定のマシン グループはどのように選択されますか? リクエストがデータセンターに入ったらルーティングするか、クライアント側でルーティングすることができます (たとえば、Javascript で、検索語の最初の X 文字に基づいてクエリする IP を決定します)。

だから、それが私がそれをする方法です。Google/Quora が扱っている膨大なデータセットを経験したことがないので、考慮していないことがあると確信しています。でも、スタートです。

そして、純粋に自宅の実験環境で私がそれを行った方法は次のとおりです。

検索する数十万件のタイトルの簡単なリストがありました。これらは専用の MongoDB コレクションにロードされ、単一のインデックスが定義されていました。次に、その前に Play Framework コントローラーを配置し、jQuery のオートコンプリート プラグインを使用して検索を行いました。

明らかに、これはあなたが探しているものと比べると小さいですが、MongoDB は、推奨事項 (つまり、優れたハードウェア、大量の RAM、メモリ内のインデックスの保持) に従えば、データセットに対して同じ種類のパフォーマンスを提供するはずです。さらに、Mongo はシャーディングをサポートし、Play フレームワークは何も共有されないため、この状況では、ユーザーベースが拡大した場合に負荷に対処するために新しいマシンを追加することは簡単です。

ちなみに、Mongo が唯一のソリューションというわけではありません。もちろん、従来の SQL データベースでも問題なく機能します。私は別の理由で Mongo を使用していました。

于 2012-09-24T11:42:53.347 に答える