2014-10-01 156 views
1

我只想返回名稱以「pizza」開頭的文檔。這是我做了什麼:爲什麼前綴返回沒有特定前綴的文檔?

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "prefix": { 
      "name": "pizza" 
     } 
     } 
    } 
    } 
} 

但我有這3個文件:

{ 
"name": "Viana Pizza", 
"city": "Mashhad", 
"address": "Vakil abad", 
"foods": ["Pizza"], 
"salad": true, 
"rate": 5.0 
} 

{ 
"name": "Pizza Pizza", 
"city": "Mashhad", 
"address": "Bahar st", 
"foods": ["Pizza"], 
"salad": true, 
"rate": 8.5 
} 

{ 
"name": "Reza Pizza", 
"city": "Tehran", 
"address": "Vali Asr", 
"foods": ["Pizza"], 
"salad": true, 
"rate": 7.5 
} 

正如你所看到的,只有其中一人有「比薩」,在名稱的開頭領域。 有什麼問題?

回答

2

可能最簡單的解釋是,你沒有提供實際的映射,你有「名稱」字段作爲「字符串」和「分析」(默認)。這意味着「Reza Pizza」將轉變爲「reza」和「披薩」條款。

而且您的過濾器將與條款匹配,而不是針對整個字段。因爲ES在分析標準映射時使用的字段和形式術語。

您需要將您的「名稱」字段更改爲「not_analyzed」或添加另一個字段來鏡像「名稱」,但該鏡像字段爲「not_analyzed」。此外,在這種情況下,對於文本「披薩」(小寫字母)的工作,您需要創建一個自定義分析器。

下面你有鏡子領域的解決方案:

PUT /pizza 
{ 
    "settings": { 
    "analysis": { 
     "analyzer": { 
     "my_keyword_lowercase_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": ["lowercase"] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "restaurant": { 
     "properties": { 
     "name": { 
      "type": "string", 
      "fields": { 
      "raw": { 
       "type": "string", 
       "analyzer": "my_keyword_lowercase_analyzer" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

而在搜索您需要使用鏡場:

GET /pizza/restaurant/_search 
{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "prefix": { 
      "name.raw": "pizza" 
     } 
     } 
    } 
    } 
} 
2

這是所有關於Elasticsearch analyzers。讓我們在prefix過濾器讀取documentation

Filters documents that have fields containing terms with a specified prefix (not analyzed). 

在這裏我們可以看到,這個過濾器方面,而不是整個字段值匹配。當您爲文檔建立索引時,ES會使用分析器將您的字段值分割爲術語。默認分析器按空格分割值,並將零件轉換爲lowercse。因此,所有三個結果都有術語匹薩在名稱字段中與pizza的術語完全匹配pizza前綴。如果你想匹配字段值 - 我建議你將地圖名稱字段設爲not_analyzed