2012-07-25 44 views
3

原諒我,如果我正在使用術語,但我有問題讓ES以對我的應用程序有意義的方式評分結果。使ElasticSearch得分高於單次打擊的tf的結果(idf?)總嵌套命中數?

我索引數千用戶的幾個簡單的字段,以及可能數百個孩子的嵌套在每個用戶的索引對象(即 - >頁數數據模型)。越來越發送到指數的JSON看起來是這樣的:

user_id: 1 
    full_name: First User 
    username: firstymcfirsterton 
    posts: 
    id: 2 
    title: Puppies are Awesome 
    tags: 
    - dog house 
    - dog supplies 
    - dogs 
    - doggies 
    - hot dogs 
    - dog lovers 

user_id: 2 
    full_name: Second User 
    username: seconddude 
    posts: 
    id: 3 
    title: Dogs are the best 
    tags: 
    - dog supperiority 
    - dog 
    id: 4 
    title: Why dogs eat? 
    tags: 
    - dog diet 
    - canines 
    id: 5 
    title: Who let the dogs out? 
    tags: 
    - dogs 
    - terrible music 

的標籤類型的「標籤」,利用「關鍵字」分析,並提振10標題沒有被提升。

當我搜索「狗」時,第一個用戶的分數高於第二個用戶。我認爲這必須做到與第一個用戶的tf-idf更高。然而在我的應用程序中,理想情況下擊中該用戶的用戶發佈的帖子越多,就會首先發布。

我嘗試按帖子數排序,但如果用戶有很多帖子,則會給出垃圾結果。基本上我想根據獨特的帖子點擊次數進行排序,這樣一個擁有更多帖子的用戶會上升到頂部。

我該如何去做這件事。有任何想法嗎?

+1

一些想法和問題。你可以發佈你如何搜索?你使用的查詢類型有很大的不同。另外,我懷疑使用「關鍵字」分析器不是一個好主意。它會將您的整個標籤變成一個單詞。一個更好的解決方案可能是使用標準分析器+自定義唯一過濾器 – Zach 2012-08-01 03:28:59

+1

@thoughtpunch,我也不明白你的問題100%,但在我看來,在你的例子中,適當的「頂級」文檔將是'post',然後它將包含一個'user_id'作爲屬性。我敢打賭搜索和整個設置會更容易。 – karmi 2012-08-01 12:24:03

回答

2

首先,我同意@karmi和@Zach,找出匹配帖子的含義非常重要。爲了簡單起見,我會假設一個匹配的帖子中有一個單詞「dog」,並且我們沒有使用關鍵字分析器來匹配標籤並提高它的趣味性。

如果我正確理解您的問題,您希望根據相關帖子的數量來訂購用戶。這意味着您需要搜索帖子才能找到相關帖子,然後將這些信息用於用戶查詢。只有將帖子分別編入索引時纔有可能,這意味着帖子必須是子文檔或嵌套字段。

假設職位子文檔,我們可以原型您的數據是這樣的:

curl -XPOST 'http://localhost:9200/test-idx' -d '{ 
    "settings" : { 
     "number_of_shards" : 1, 
     "number_of_replicas" : 0 
    }, 
    "mappings" : { 
     "user" : { 
     "_source" : { "enabled" : true }, 
     "properties" : { 
      "full_name": { "type": "string" }, 
      "username": { "type": "string" } 
     } 
     }, 
     "post" : { 
     "_parent" : { 
      "type" : "user" 
     }, 
     "properties" : { 
      "title": { "type": "string"}, 
      "tags": { "type": "string", "boost": 10} 
     } 
     } 
    } 
}' && echo 

curl -XPUT 'http://localhost:9200/test-idx/user/1' -d '{ 
    "full_name": "First User", 
    "username": "firstymcfirsterton" 
}' && echo 
curl -XPUT 'http://localhost:9200/test-idx/user/2' -d '{ 
    "full_name": "Second User", 
    "username": "seconddude" 
}' && echo 

#Posts of the first user 
curl -XPUT 'http://localhost:9200/test-idx/post/1?parent=1' -d '{ 
    "title": "Puppies are Awesome", 
    "tags": ["dog house", "dog supplies", "dogs", "doggies", "hot dogs", "dog lovers", "dog"] 
}' && echo 
curl -XPUT 'http://localhost:9200/test-idx/post/2?parent=1' -d '{ 
    "title": "Cats are Awesome too", 
    "tags": ["cat", "cat supplies", "cats"] 
}' && echo 
curl -XPUT 'http://localhost:9200/test-idx/post/3?parent=1' -d '{ 
    "title": "One fine day with a woof and a purr", 
    "tags": ["catdog", "cartoons"] 
}' && echo 

#Posts of the second user 
curl -XPUT 'http://localhost:9200/test-idx/post/4?parent=2' -d '{ 
    "title": "Dogs are the best", 
    "tags": ["dog supperiority", "dog"] 
}' && echo 
curl -XPUT 'http://localhost:9200/test-idx/post/5?parent=2' -d '{ 
    "title": "Why dogs eat?", 
    "tags": ["dog diet", "canines"] 
}' && echo 
curl -XPUT 'http://localhost:9200/test-idx/post/6?parent=2' -d '{ 
    "title": "Who let the dogs out?", 
    "tags": ["dogs", "terrible music"] 
}' && echo 

curl -XPOST 'http://localhost:9200/test-idx/_refresh' && echo 

我們可以通過Top Children Query查詢這些數據。 (或者在嵌套字段的情況下,我們可以使用實現類似Nested Query結果)

curl 'http://localhost:9200/test-idx/user/_search?pretty=true' -d '{ 
    "query": { 
    "top_children" : { 
     "type": "post", 
     "query" : { 
      "bool" : { 
       "should": [ 
        { "text" : { "title" : "dog" } }, 
        { "text" : { "tags" : "dog" } } 
       ] 
      } 
     }, 
     "score" : "sum" 
    } 
    } 
}' && echo 

這個查詢將首先返回,因爲那是來自匹配標籤極大提升因素的第一個用戶。所以,它可能看起來不像你想要的,但有一些簡單的方法來解決它。首先,我們可以減少標籤字段的增強因子。特別是對於可以重複多次的領域來說,10是非常大的因素。或者,我們可以修改查詢無視孩子的得分命中完全和使用的頂部匹配子文檔的數量爲比分反超:

curl 'http://localhost:9200/test-idx/user/_search?pretty=true' -d '{ 
    "query": { 
    "top_children" : { 
     "type": "post", 
     "query" : { 
      "constant_score" : { 
       "query" : {    
        "bool" : { 
         "should": [ 
          { "text" : { "title" : "dog" } }, 
          { "text" : { "tags" : "dog" } } 
         ] 
        } 
       } 
      } 
     }, 
     "score" : "sum" 
    } 
    } 
}' && echo