2015-10-14 65 views
0

我有權訪問Neo4J圖形數據庫,其中存儲了人員列表以及他們之間的關係(朋友)。我正在尋找實施「搜索朋友列表」功能,在給定的用戶朋友列表中執行搜索。我擔心性能,所以我正在尋找使用Elasticsearch來實現此搜索;但我不確定如何在Elasticsearch中從Neo4j索引用戶數據以便於上述查詢。一個典型的用例是「爲用戶X找到他的朋友,其名稱開頭‘Mik的’的SearchAPI是使用Elasticsearch的JavaAPI建立在SpringWebElasticsearch商店的可搜索列表

編輯1:

我所問的是不同的到this,因爲我知道如何使用Elasticsearch河流和其他工具來索引數據,我的問題是尋求實現諸如「search_friends_list」之類的功能的最佳方法,例如,我是否使用每個用戶的唯一用戶標識符作爲鍵入(類似於..:9200/users/[username])並將給定用戶的每個朋友編入索引並鍵入?這種方式如果我想通過用戶JackSparrow的朋友列表進行搜索,我會執行類似於t o ..:9200/users/JackSparrow/_search?q=search_term。這個例子雖然有些味道,並且當我的系統中的用戶數量增長時,可能會導致嚴重的性能下降。那就是我需要幫助和建議的地方。存在哪些方法來實現這樣的解決方案?

編輯2:除去Neo4j的標記,提供了更多的信息

映射

{ 
    "people": { 
     "mappings": { 
      "friends": { 
       "properties": { 
        "firstname": { 
         "type": "string" 
        }, 
        "friends": { 
         "type": "string" 
        }, 
        "fullname": { 
         "type": "string" 
        }, 
        "id": { 
         "type": "long" 
        }, 
        "lastname": { 
         "type": "string" 
        }, 
        "username": { 
         "type": "string" 
        }, 
        "userid": { 
         "type": "string" 
        } 
       } 
      } 
     } 
    } 
} 

數據

{ 
    "_index": "people", 
    "_type": "friends", 
    "_id": "24482ba5-06fa-2f58-2560-4b8fa5e3d1a7", 
    "_score": 11.5473, 
    "_source": { 
     "firstname": "Carl", 
     "id": 4735, 
     "fullname": "Carl Platt", 
     "userid": "24482ba5-06fa-2f58-2560-4b8fa5e3d1a7", 
     "friends": [ 
      "8248f90b-3c30-b60a-d64f-ced55304fcb0", 
      "8b4a0960-f792-87d5-be4d-17a53963c29e", 
      "904a4d6f-c7ce-8ae3-edf2-e0ac6bc69885", 
      "934e0e4b-2b20-b7b1-c092-1eb22e3e92bd", 
      "954e1500-7f74-468e-b611-cd35382d9aa6", 
      "994cacfc-3a76-c77a-adec-b50804933490", 
      "a942b4b7-cdcc-8653-ef73-a6000dbd418c", 
      ... 

查詢

{ 
    "query": { 
    "filtered": { 
     "query": { 
     "query_string": { 
      "default_field": "firstname", 
      "query": "Amu*"   
     } 
     }, 
     "filter": { 
     "terms": { 
      "friends": { 
      "index": "people", 
      "type": "friends", 
      "id": "24482ba5-06fa-2f58-2560-4b8fa5e3d1a7",    
      "path": "userid" 
      } 
     } 
     } 
    } 
    } 
} 
+0

問題是不同的。我只提到Neo4J,所以沒有人會說「使用neo4j」 – emilio

+0

我會刪除標誌:) –

回答

2

在官方文檔中,有爲了說明terms lookup mechanism,這很可能你在找什麼圍繞Twitter的用戶和他們的鳴叫類似的例子。

這個想法是有一個users索引包含user文件。代表用戶的每個文檔都會有一個數組屬性,其中包含他的朋友的ID。讓我們創建users指數的一個簡單的版本:

curl -XPUT localhost:9200/users -d '{ 
    "mappings": { 
    "user": { 
     "properties": { 
     "id": { 
      "type": "integer" 
     }, 
     "name": { 
      "type": "string" 
     }, 
     "friends": { 
      "type": "integer" 
     } 
     } 
    } 
    } 
}' 

現在,讓我們指數的一些樣本數據,其中用戶1的朋友與所有其他用戶,但4(邁克):

curl -XPOST localhost:9200/users/user/_bulk -d ' 
{"index":{"_id":1}} 
{"id": 1, "name": "John", "friends": [2,3,5]} 
{"index":{"_id":2}} 
{"id": 2, "name": "Mikil", "friends": [1,3]} 
{"index":{"_id":3}} 
{"id": 3, "name": "Maxim", "friends": [1,2]} 
{"index":{"_id":4}} 
{"id": 4, "name": "Mike", "friends": [5]} 
{"index":{"_id":5}} 
{"id": 5, "name": "Philip", "friends": [1,4]} 
' 

所以我重述的典型的用例之一,即「爲用戶X找到他的朋友,其名稱開頭‘Mik的’有了這樣一個建立這可以用下面的查詢來實現:

curl -XPOST localhost:9200/users/user/_search -d '{ 
    "query": { 
    "filtered": { 
     "query": { 
     "query_string": { 
      "default_field": "name", 
      "query": "mik*"   <--- only friends whose name starts with "mik" 
     } 
     }, 
     "filter": { 
     "terms": { 
      "friends": { 
      "index": "users", 
      "type": "user", 
      "id": "1",   <--- only friends of user 1 
      "path": "id" 
      } 
     } 
     } 
    } 
    } 
}' 

結果將只包含用戶2(Mikil)而不是4(Mike)。 QED。

+0

隨着過濾器(上面)限制搜索「僅用戶1的朋友」以加速對用戶1的朋友的後續完成請求。 –

+0

@Val當userID是一個整數時,它的工作方式非常出色,但是,當我使用UUID(因爲是我當前系統上的需求),它似乎不起作用。我錯過了什麼嗎? – emilio

+0

不應該有任何區別。你能分享一些樣本文件,爲什麼你認爲它不適用於字符串ID? – Val