2015-10-23 139 views
9

鑑於短語匹配查詢是這樣的:分組match_phrase搜索按匹配文本導致彈性搜索

{ 
    'match_phrase': { 
     'text.english': { 
      'query': "The fox jumped over the wall", 
      'phrase_slop': 4, 
     } 
    } 
} 

有沒有一種方式,通過精確匹配,我可以組的結果嗎?

因此,如果我有一個文件text.english包含「快速狐狸跳過小牆」和3個文件包含「懶惰的狐狸跳過大牆」,我最終得到這兩組結果。

我很確定運行多個查詢並在ES之外進行一些處理,但我需要一個能夠合理執行大量文檔的解決方案。理想情況下,我希望有一種方法可以使用我錯過的聚合來做到這一點。

我想出的最佳解決方案是運行上面的高亮查詢,解析出所有結果的所有亮點,並根據亮點內容對它們進行分組。對於非常小的結果集來說這很好,但是在超過1000個文檔結果集中,它非常慢。

編輯: 也許我可以使這一點更清楚。如果我有以下值的示例文檔:

  1. 「快速的狐狸跳過小牆,等等。
  2. 「懶惰的狐狸跳過了大牆,Blah等等說了許多不相關的文字。」
  3. 「懶惰的狐狸跳過了大牆,Blah等等說了許多不相關的文字。」
  4. 「懶惰的狐狸跳過了大牆,Blah等等說了許多不相關的文字。」

我希望能夠到組我的結果與查詢文本如下「狐狸越牆」:

  • 「快速狐狸躍過小牆」 - 文件1
  • 「懶惰的狐狸跳過大牆」 - 文檔2,3,4
+0

你想達到什麼目的?從這兩個樣本文件中,你能解釋什麼應該是理想的結果? –

+0

好的,所以你想讓你的查詢匹配,但結果應該按照它們匹配的文本進行分組?對'text.english.raw'的簡單聚合應該做到這一點(其中'.raw'是一個'not_analyzed'子字段)。 –

+0

的確如此,我想用完全匹配文本對結果進行分組。我有一個分析和每個文檔的原始副本。聚合如何工作?我找不到那樣做。 –

回答

2

在我看來,highlighting是唯一的選擇,因爲它是Elasticsearch會顯示匹配文本的這「部分」的唯一途徑。在你的情況下,你想根據什麼「匹配」將文檔分組。

如果文本會更短(如少數詞),也許更多涉及的解決方案是將文本拆分爲shingle -kind的方式,不知何故組對這些短語... 也許

但對於文本的頁面,我認爲唯一的選擇是使用高亮和事後執行額外的步驟,以組的突出部分。

2

如果text.english中的語句「完全相同」,那麼它們的分數應該相同。您可以基於Elastic Search _score來彙總結果。

請參閱本自ES禁用了動態腳本SO質疑ElasticSearch: aggregation on _score field?

,這可能幫助。 ElasticSearch: aggregation on _score field w/ Groovy disabled

+0

謝謝,我沒有想到這一點。它非常接近,但問題在於,當文本被分析和阻止時,我會有一些不同的匹配,但得分相同(例如上面的兩個示例短語)。 –

+0

呃,也許我上面的評論是誤導性的。我阻止了字段索引的原始版本。我想複雜度是因爲我想在比賽中匹配,並將比賽按原始分組。 –

+0

剛剛看到您的編輯。既然你有「Blah blah blah blah blah blah many pages of unrelated text。」,ES'_score'會有所不同,也不能像其他用戶所建議的那樣使用詞彙彙總,因爲相同的原因 – ChintanShah25

-1

我相信你可以在未分析的字段中創建術語聚合。

如果text.raw定義爲not_analyzed,則聚合應採用整個字段值。

我沒有測試過,但我發現很類似:ElasticSearch terms aggregation by entire field

+0

整個領域都不行,可悲 - 我需要*只是*比賽。我會更新這個例子 –

0

我在產品搜索應用程序中有類似的問題/挑戰我想按品牌分組產品,例如

Nikon 
Nikos 

要解決此問題,我正在試驗Suggester 。背後的想法是,建議者會爲我提供我的搜索建議。這些建議將被分組,並且不會對所有文檔重複(即使可能有其他文字)。您可以使用Term SuggesterPhrase Suggester

但是,此方法需要您更改結果的處理。您必須將建議顯示爲組並單獨處理搜索結果。這種方法的優點是你不必自己分組。

另一種解決方案是使用帶狀皰疹的Terms Aggregation。這種聚合將分組詞組(帶狀皰疹)。但是,要獲得結果,必須採取所有聚合並將其與查詢輸入相匹配。見示例映射,數據和查詢:

PUT /so 
{ 
    "settings": { 
     "analysis": { 
     "analyzer": { 
      "suggestion_analyzer": { 
       "tokenizer": "standard", 
       "filter": [ 
        "lowercase" 
       ] 
      }, 
      "analyzer_shingle": { 
       "type": "custom", 
       "tokenizer": "standard", 
       "filter": [ 
        "filter_shingle" 
       ] 
      } 
     }, 
     "filter": { 
      "filter_shingle": { 
       "type": "shingle", 
       "min_shingle_size": 4, 
       "max_shingle_size": 16, 
       "output_unigrams": "false" 
      } 
     } 
     } 
    }, 
    "mappings": { 
     "d": { 
     "properties": { 
      "text": { 
       "properties": { 
        "english": { 
        "type": "string", 
        "fields": { 
         "shingles": { 
          "type": "string", 
          "analyzer": "analyzer_shingle" 
         }, 
         "suggest": { 
          "type": "completion", 
          "index_analyzer": "analyzer_shingle", 
          "search_analyzer": "analyzer_shingle", 
          "payloads": true 
         } 
        } 
        } 
       } 
      } 
     } 
     } 
    } 
} 

文獻1:

POST /so/d/1 
{ 
    "text": { 
     "english": "The quick fox jumps over the big wall. JJKJKJKJ" 
    } 
} 

文獻2:

POST /so/d/2 
{ 
    "text": { 
     "english": "The quick fox jumps over the small wall. JJKJKJKJ" 
    } 
} 

文獻3:

POST /so/d/3 
{ 
    "text": { 
     "english": "The quick fox jumps over the gugus wall. LLLLLLL" 
    } 
} 

查詢:

POST /so/_search 
{ 
    "size": 0, 
    "query": { 
     "match": { 
      "text.english": "The quick fox jumps over the wall" 
     } 
    }, 
    "aggs" : { 
     "states" : { 
      "terms" : { 
       "field" : "text.english.shingles", 
       "size": 40 
      } 
     } 
    } 
}