2016-05-13 60 views
1

我做了一個非常簡單的測試。我建立了一個學生的索引和類型,然後我定義的映射:錯誤的索引彈性搜索使用分析器

POST student 
{ 

    "mappings" : { 
     "ing3" : { 
      "properties" : { 
       "quote": { 
        "type": "string", 
        "analyzer": "english" 
       } 
      } 
     } 
    } 
} 

之後,我三年級的學生加入到這個索引:

POST /student/ing3/1 
{ 
    "name": "Smith", 
    "first_name" : "John", 
    "quote" : "Learning is so cool!!" 
} 

POST /student/ing3/2 
{ 
    "name": "Roosevelt", 
    "first_name" : "Franklin", 
    "quote" : "I learn everyday" 
} 

POST /student/ing3/3 
{ 
    "name": "Black", 
    "first_name" : "Mike", 
    "quote" : "I learned a lot at school" 
} 

在這一點上我認爲英語tokeniser將tokenise在我所有的報價的話,所以如果我做一個搜索,如:

GET /etudiant/ing3/_search 
{ 
    "query" : { 
     "term" : { "quote" : "learn" } 
    } 
} 

我將所有的文件,結果因爲我的tokeniser將等於「學習,學習,學會了」我是對的。但是,當我嘗試這個請求:

GET /student/ing3/_search 
{ 
    "query" : { 
     "term" : { "quote" : "learned" } 
    } 
} 

我得到了零命中,在我看來,我應該有第三個文件(至少?)。但對我來說Elasticsearch也應該索引learnedlearning不僅learn。我錯了嗎?我的要求錯了嗎?

回答

1

如果檢查:

GET 'index/_analyze?field=quote' -d "I learned a lot at school" 

,你會看到你的句子被分析爲:

{ 
    "tokens":[ 
     { 
     "token":"i", 
     "start_offset":0, 
     "end_offset":1, 
     "type":"<ALPHANUM>", 
     "position":0 
     }, 
     { 
     "token":"learn", 
     "start_offset":2, 
     "end_offset":9, 
     "type":"<ALPHANUM>", 
     "position":1 
     }, 
     { 
     "token":"lot", 
     "start_offset":12, 
     "end_offset":15, 
     "type":"<ALPHANUM>", 
     "position":3 
     }, 
     { 
     "token":"school", 
     "start_offset":19, 
     "end_offset":25, 
     "type":"<ALPHANUM>", 
     "position":5 
     } 
    ] 
} 

所以英語儀去除punctions和停止詞和記號化的話在他們的根形式。

https://www.elastic.co/guide/en/elasticsearch/guide/current/using-language-analyzers.html

您可以使用match查詢這也將分析你的搜索文本,以便將匹配:

GET /etudiant/ing3/_search 
{ 
    "query" : { 
     "match" : { "quote" : "learned" } 
    } 
} 
1

還有另一種方式。您可以幹條款(english分析確實有一個詞幹),而且還保留了原有條款,通過使用keyword_repeat token filter,然後用unique token filter"only_on_same_position": true詞幹後刪除不必要的重複:

PUT student 
{ 
    "settings": { 
    "analysis": { 
     "analyzer": { 
     "myAnalyzer": { 
      "type": "custom", 
      "tokenizer": "standard", 
      "filter": [ 
      "english_possessive_stemmer", 
      "lowercase", 
      "english_stop", 
      "keyword_repeat", 
      "english_stemmer", 
      "unique_stem" 
      ] 
     } 
     }, 
     "filter": { 
     "unique_stem": { 
      "type": "unique", 
      "only_on_same_position": true 
     }, 
     "english_stop": { 
      "type": "stop", 
      "stopwords": "_english_" 
     }, 
     "english_stemmer": { 
      "type": "stemmer", 
      "language": "english" 
     }, 
     "english_possessive_stemmer": { 
      "type": "stemmer", 
      "language": "possessive_english" 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "ing3": { 
     "properties": { 
     "quote": { 
      "type": "string", 
      "analyzer": "myAnalyzer" 
     } 
     } 
    } 
    } 
} 

在這種情況下,term查詢也會起作用。如果你看看什麼樣的條件真的被編入索引:

GET /student/_search 
{ 
    "fielddata_fields": ["quote"] 
} 

這將是很清楚,爲什麼現在它匹配:

"hits": [ 
    { 
     "_index": "student", 
     "_type": "ing3", 
     "_id": "2", 
     "_score": 1, 
     "_source": { 
      "name": "Roosevelt", 
      "first_name": "Franklin", 
      "quote": "I learn everyday" 
     }, 
     "fields": { 
      "quote": [ 
       "everydai", 
       "everyday", 
       "i", 
       "learn" 
      ] 
     } 
    }, 
    { 
     "_index": "student", 
     "_type": "ing3", 
     "_id": "1", 
     "_score": 1, 
     "_source": { 
      "name": "Smith", 
      "first_name": "John", 
      "quote": "Learning is so cool!!" 
     }, 
     "fields": { 
      "quote": [ 
       "cool", 
       "learn", 
       "learning", 
       "so" 
      ] 
     } 
    }, 
    { 
     "_index": "student", 
     "_type": "ing3", 
     "_id": "3", 
     "_score": 1, 
     "_source": { 
      "name": "Black", 
      "first_name": "Mike", 
      "quote": "I learned a lot at school" 
     }, 
     "fields": { 
      "quote": [ 
       "i", 
       "learn", 
       "learned", 
       "lot", 
       "school" 
      ] 
     } 
    } 
    ]