2012-05-21 24 views
20

我正嘗試使用ElasticSearch創建具有社交功能的商業搜索。我有一個企業目錄,用戶可以以不同的方式對這些企業的互動:通過回顧它們,檢查放進去,等ElasticSearch如何用於實現社交搜索?

當企業用戶搜索,我希望能夠向他們展示了他們的朋友在結果頂部與之交互的企業(或基於這些互動進行篩選)。 設置我的索引以達到此目的的最佳方式是什麼?

我能想到的有幾個可能的解決辦法,但我與ES一個初學者,我不知道什麼會引起問題:

  1. 我可以使用多tennancy並創建一個單獨的索引爲每個用戶。我排除了這一點,因爲用戶數量遠遠大於企業數量或用戶特定內容數量。

  2. 我可以添加用戶/得分對的列表,每個索引的業務。與業務交互的每個用戶都會在其中,並且分數將表示他們與業務進行的交互量(這足以滿足我的過濾/排序目的)。每次他們與業務互動時,我都會更新索引中的分數。問題在於我只關心朋友的活動,所以我需要找出一些方法,在爲業務創建綜合評分時考慮我的朋友是誰。我不知道如何在ES中做到這一點。

  3. 我可以創建一個類似的計劃,但不是讓我的相互作用的得分爲商業,得分將反映我的朋友與商家的互動。這消除了在ElasticSearch中對我的社交圖進行建模的需求,但這確實意味着只要有人與某個企業進行交互,我就需要更新他們所有朋友的分數。這也意味着每個企業的用戶/分數對列表將會更大,因爲它需要包括任何擁有與該企業進行互動的朋友的人。

  4. 最終的解決方案,我能想到的是要保持跟蹤發生在一個企業每一個人的互動,並把它添加到ES業務的文件。這對我來說似乎並不現實 - 它結合了其他解決方案的問題。但它可能是保持索引最新的最直接的方法。

感謝您的幫助!

+1

我正面臨一個類似的問題 - 大家分享你最終怎麼做? – EugeneMi

回答

8

我正在投票修改#2。

不是存儲業務文檔本身內部的每個用戶/分對,我想創建一個父/子關係。這可以讓您更新孩子的分數(用戶分數),而無需重新索引整個業務文檔(以及所有其他用戶分數)。

查看此頁面爲一個偉大的教程父母/子女約有一半時:http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/

然後你可以使用一個has_child filtertop_children query只查找你的朋友有得分的企業。關於訂購兒童文件有幾點注意事項,但該教程涵蓋了這些內容,因此請確保您閱讀到底部。

然後,我只是執行所有「非社會」排名搜索的正常查詢。

或者,您可以將所有內容混合在一起,併爲您的朋友所取得的比賽添加提升量,以便所有事情均可適當地進行排名。執行兩個查詢並將它們自己組合起來可能會更容易。

5

還有另外一套解決方案具有極快的優勢(即充分利用ES的最佳優勢),但對於任何人甚至知道設計數據存儲/檢索系統的第一件事情而言,這都很可怕。

如果你的 '生意' 指數比你的 '用戶' 指數(即萬BIZ 1,000,000用戶)小

  1. 創建2個指標:用戶業務
  2. 業務指標應該有保存誰曾經「互動」與它(即「用戶:1,4,23,26,127,8678」)每個用戶的ID的「數組」字段
  3. 用戶指標應該有

當你搜索一個企業,做與元信息的嵌套對象業務ID和評論,簽到等(即「:1233,評分:7.5,簽入21 business_id」)嵌套數組場一個快速的字符串查詢或過濾查詢與用戶的朋友ID(當然OR)對商業指數。 tf-idf應該自動篩選與您的朋友進行過最多互動的企業。如果您需要更多信息,只需點擊用戶索引即可獲取每位朋友的元數據(評分,簽到等)。這應該是快速和超高效的,因爲ES在將數組匹配爲單個條款方面絕對精彩。這是喲!

如果您的'商業'索引顯着大於'用戶'索引,請反轉該模式...將用戶在用戶索引中與用戶交互過的business_id的索引數組排序。

+0

我對ES很新,但是當你創建用戶索引時,你是不是免費獲得用戶索引?基本上,Business index是用戶索引中business_id字段的反向索引 – EugeneMi

3

只是在這裏吐了口水,但我想我想要使用像Neo4J這樣的圖形數據庫,在這裏查詢「我朋友檢查過的企業」這樣的查詢並查詢數據庫和elasticsearch同時首先從圖形數據庫返回結果。或者您可以獲得該圖形查詢的結果並與elasticsearch中的結果相匹配(匹配ID),然後將查詢時間提升應用於彈性搜索結果,以便將它們浮動到返回結果的頂部。

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的朋友。