2015-10-16 49 views
1

我有這3個對象(3個用戶的照片,並且每一張照片都有一個類別ID)Elasticsearch分數與子文檔數

{ 
    "id": 1, 
    "name": "User1", 
    "photos":[ 
     { 
      "id": 1, 
      "cat": 1 
     }, 
     { 
      "id": 2, 
      "cat": 1 
     }, 
     { 
      "id": 3, 
      "cat": 2 
     } 
    ] 
} 
{ 
    "id": 2, 
    "name": "User2", 
    "photos":[ 
     { 
      "id": 4, 
      "cat": 1 
     }, 
     { 
      "id": 5, 
      "cat": 2 
     }, 
     { 
      "id": 6, 
      "cat": 2 
     } 
    ] 
} 
{ 
    "id": 3, 
    "name": "User3", 
    "photos":[ 
     { 
      "id": 7, 
      "cat": 2 
     }, 
     { 
      "id": 8, 
      "cat": 3 
     }, 
     { 
      "id": 9, 
      "cat": 3 
     } 
    ] 
} 

我想給一個分數(最高分:10)對這些文件因有多少照片,他們有貓= 1

Object1 : 2 objects with cat = 1 
Object2 : 1 objects with cat = 1 
Object3 : 0 objects with cat = 1 

這樣的比分將Object1 = 10,對象2 = 5,Object3 = 0

+1

你能預處理文件在索引它們之前在Elasticsearch中添加一個cat1字段,例如計數cat = 1張照片(或者你想要的分數)?然後你可以簡單地排序這個領域,而不是陷入得分和腳本。 – eemp

回答

2

無論什麼@eemp說,或者如果您不能修改方式文件被索引和/或如果不能修改的映射,則一個解決方案是利用一個function_score query與其中我們訪問photos陣列和乘以5具有cat == 1元件的數量的script_score組件。

{ 
    "query": { 
    "function_score": { 
     "query": { 
     "match_all": {} 
     }, 
     "functions": [ 
     { 
      "script_score": { 
      "script": "_source.photos.findAll{return it.cat == 1}.size() * 5" 
      } 
     } 
     ] 
    } 
    } 
} 

你會得到你所期望的分數,即

  • 10物體1
  • 5對象2
  • 0對象3
+0

我現在正在做類似的事情......但是我開始這個話題的原因是最高分......你只需將每張照片乘以5 ....所以分數可以增加超過10 ... 我想最大比分總是10 .. 如果用戶擁有100張照片與貓= 1 .....他的得分將是0-10之間(取決於其他用戶有多少照片有) – Michalis

+0

所以你希望你的分數始終在[0,10]區間內? – Val

+0

請注意,您可以隨時在客戶端標準化分數,因爲您將爲每個文檔獲得'max_score'和'_score',因此客戶端中的公式應該像'10 * hit._score/max_score'一樣簡單。 – Val