20

ElasticSearch を使用して、ソーシャル機能を備えたビジネス検索を作成しようとしています。私はビジネス ディレクトリを持っており、ユーザーはさまざまな方法でそれらのビジネスと対話できます。たとえば、レビュー、チェックインなどです。

ユーザーがビジネスを検索するときに、友人がやり取りしたビジネスを結果の上部に表示できるようにしたいと考えています (または、それらのやり取りに基づいてフィルタリングします)。 これを達成するためにインデックスを設定する最良の方法は何ですか?

考えられる解決策はいくつかあると思いますが、私は ES の初心者であり、何が問題を引き起こすのかわかりません。

  1. マルチテナンシーを使用して、ユーザーごとに個別のインデックスを作成できます。ユーザーの数は、ビジネスの数やユーザー固有のコンテンツの量よりもはるかに多いため、これを除外しました。

  2. ユーザーとスコアのペアのリストを、インデックス付けされた各ビジネスに追加できます。ビジネスとやり取りしたすべてのユーザーがそこにいて、スコアは彼らがビジネスとやり取りした量を表します (これは私のフィルタリング/並べ替えの目的には十分です)。彼らがビジネスとやり取りするたびに、インデックスのスコアを更新します。これの問題は、友人の活動しか気にしないことです。そのため、ビジネスの複合スコアを作成するときに、友人が誰であるかを考慮する方法を見つける必要があります。ESでこれを行う方法がわかりません。

  3. 同様のスキームを作成することもできますが、ビジネスとのやり取りのスコアを保持する代わりに、スコアはビジネスとの友人のやり取りを反映します。これにより、ElasticSearch でソーシャル グラフをモデル化する必要がなくなりますが、ある人がビジネスとやり取りするたびに、すべての友人のスコアを更新する必要があります。また、各ビジネスのユーザー/スコアのペアのリストが大きくなることも意味します。これは、ビジネスとやり取りした友人がいる人を含める必要があるためです。

  4. 私が考えることができる最終的な解決策は、ビジネスに発生するすべての個々のやり取りを追跡し、それを ES のビジネス文書に追加することです。これは私には現実的ではないように思えます。他の解決策の問題を組み合わせたものです。しかし、インデックスを最新の状態に保つという点では、おそらく最も簡単な方法です。

ご協力いただきありがとうございます!

4

5 に答える 5

8

私は修正された#2に投票しています。

各ユーザー/スコアのペアをビジネスドキュメント自体の中に保存する代わりに、親/子の関係を作成します。これにより、ビジネスドキュメント全体(および他のすべてのユーザースコア)のインデックスを再作成しなくても、子のスコア(ユーザースコア)を更新できます。

このページをチェックして、親/子のすばらしいチュートリアルを確認してください:http ://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/

次に、has_childフィルターまたはtop_childrenクエリを使用して、友達がスコアを付けているビジネスのみを検索できます。子のドキュメントの注文に関していくつかの注意点がありますが、それはそのチュートリアルでカバーされているので、必ず一番下まで読んでください。

次に、すべての「非ソーシャル」ランクの検索に対して通常のクエリを実行します。

または、すべてをまとめて、友達が獲得した試合にブーストを追加して、すべてが適切にランク付けされるようにすることもできます。2つのクエリを実行して、それらを自分で組み合わせる方が簡単な場合があります。

于 2012-08-01T04:20:53.217 に答える
5

非常に高速であるという利点を持つ別のソリューション セットがあります (つまり、ES の長所を利用する) が、データ ストレージ/検索システムの設計について最初から知っている人にはひどいものに見えます。

「ビジネス」インデックスが「ユーザー」インデックスよりも小さい場合 (つまり、10,000 ビジネス、1,000,000 ユーザー)

  1. UserBusinessの2 つのインデックスを作成します。
  2. ビジネス インデックスには、それと「対話」したことのあるすべてのユーザーの ID を保持する「配列」フィールドが必要です (つまり、「ユーザー: 1,4,23,26,127,8678」)。
  3. ユーザー インデックスには、メタ情報を含むネストされたオブジェクト内のビジネス ID とレビュー、チェックインなどを含むネストされた配列フィールドが必要です (例: "business_id:1233,rating: 7.5,checkins:21")。

ビジネスを検索するときは、ビジネス インデックスに対してユーザーの友人 ID (またはもちろん) を使用して、簡単な文字列クエリまたはフィルター クエリを実行します。tf-idf は、友達が最も多くやり取りしたビジネスを自動的にフィルター処理して上位に表示する必要があります。さらに情報が必要な場合は、ユーザー インデックスをクリックして、各フレンドのメタ データ (評価、チェックインなど) を取得します。ES は個々の用語として配列を一致させるのに非常に優れているため、これは非常に高速で非常に効率的です。それがあなたのためのものです!

「ビジネス」インデックスが「ユーザー」インデックスよりも大幅に大きい場合は、パターンを逆にして、ユーザーが操作した business_ids のインデックス付き配列をユーザー インデックスに配置します。

于 2012-09-02T13:22:21.827 に答える
1

Solr は、GraphQuery オペレーターを使用してこれを行うことができます。

https://issues.apache.org/jira/browse/SOLR-7543

「node_id」のフィールドと「edge_id」の(多値)フィールドを含むドキュメントをインデックスに入れることができます

これを構造化するには、いくつかの方法があります。

  1. フレンド ID のリストを含むユーザー ドキュメントを作成できます。または
  2. ユーザー レコード間をリンクするリンク テーブルである別のテーブルを持つことができます。

ケース 1 の場合: 「user_id」を含むフィールドと「friend_ids」を含む別のフィールドを使用して、システム内の各ユーザーのドキュメントにインデックスを付けます。

その時点で、ユーザー 555 のすべての友達を検索するには、次のようにします。

{!graph from="user_id" to="friend_ids" maxDepth=1}user_id:555

ユーザーの友達の友達を探すため

{!graph from="user_id" to="friend_ids" maxDepth=2}user_id:555

場所フィールドなど、ユーザー レコードに他のメタデータ フィールドがある場合は、それをトラバーサル フィルターとして追加して、ボストンに住んでいる私の友人を見つけることができます。このトラバーサル フィルタは、各ホップに適用されます。

{!graph from="user_id" to="friend_ids" maxDepth=2 traversalFilter="location:Boston"}user_id:555

上記のクエリは、ボストンに住んでいるユーザー 555 の友人である、ボストンに住んでいる友人を検索します。

于 2016-02-15T20:04:11.630 に答える