2

私はソーシャル ネットワークをセットアップしており、API を介してエントリを検索したいと考えています。ソーシャル ネットワークのデータベースは mysql です。検索で次の形式で結果が返されるようにしたい: クエリに一致し、検索を実行しているユーザーの友人である結果は、単にクエリに一致する結果よりも優先される必要があります。

これは 1 つのクエリで実行できますか、それとも 2 つの別個のクエリを実行して結果をマージし、重複を削除する必要がありますか?

Lucene を使用してデータ構造を構築し、そのインデックスを効率的に検索することもできますが、新しい関係が作成されるたびにドキュメントを更新するというペナルティが大きすぎるのではないかと考えています。

ありがとう

4

2 に答える 2

1

Lucene への参照は、式を少し複雑にします。最初にそれなしで解決しましょう (または少なくともベースラインを取得します)。

次のデータモデル(またはそれに近いもの)を想定しています。

tblUsers
  ユーザー ID PK
  ユーザー名
  年
  ...

tblBuddies
  UserId tblUsers.UserId への FK
  FriendId tblUsers.Userid = 友達の 1 人の ID
  BuddyRating float 0.0 から 1.0 (または任意の正規化されたスケール) を示す
                  友情/類似性のレベル/何でも

tblItems
  アイテム ID PK
  項目名
  説明
  価格
  ...

tblUsersToItems
   UserId tblUsers.UserId への FK
   ItemId FK へ
   ItemRating float 0.0 から 1.0 (または正規化されたスケール) を示す
                ユーザーによってアイテムに割り当てられた「値」。

単純なクエリ (ただし、最適化されたクエリの良い基礎) は次のようになります。

SELECT [TOP 25] I.ItemId, ItemName, Description, SUM(ItemRating * BuddyRating)
FROM tblItems I
LEFT JOIN tblUserToItems UI ON I.ItemId = UI.ItemId
LEFT JOIN tblBuddies B ON UI.UserId = B.FriendId
WHERE B.UserId = 'IdOfCurrentUser'
  AND SomeSearchCriteria -- ItemName = 'MP3 Player' と言います。
GROUP BY I.ItemId、ItemName、説明
ORDER BY SUM(ItemRating * BuddyRating) DESC

アイデアは、特定のアイテムが友人によって推奨/使用された場合に、より重み付けされるというものです。友人が親しい友人 [BuddyRating] である場合、および/または友人がこのアイテムをより強く推奨している場合 [ItemRating] は、余分な体重がより重要になります。

このようなクエリの最適化は、アイテムの総数、特定のユーザーが持つ仲間の平均/最大数、ユーザーが自分のリストに持つ可能性のあるアイテムの平均/最大数に依存します。

あなたが求めているのはこのタイプのアイデア/情報ですか、それとも質問を見逃していますか?

于 2009-11-22T21:41:21.380 に答える
1

1 つの方法は、すべてのソーシャル ネットワーク グラフを Lucene とは別に保存することです。Lucene でキーワード クエリを実行し、ネットワーク グラフ内のすべてのフレンドを検索します。返されたすべての友達について、それらのすべての友達の検索結果を何らかの要因と手段でブーストします。この再ソートは、Lucene の外部で行われます。私は以前にこのようなことをしたことがあり、かなりうまく機能します。

Lucene でヒットが収集されるときにブーストを行うカスタム HitCollector を作成することもできます。現在のユーザーの友人に属する内部 Lucene ID のリストを作成する必要があります。

ソーシャル ネットワーク グラフは、疎な隣接行列としてメモリに Mysql に保存するか、Neo4jを参照してください。

于 2009-11-23T15:21:03.073 に答える