了解ElasticSearch分析器
令人遺憾的是,許多早期的互聯網啤酒配方不一定采用易于消化的格式。 也就是說,這些食譜是通常在電子郵件或論壇帖子中最初組成的非結構化的方向和成分混合列表。
因此,盡管很難輕松地將這些配方放入傳統的數據存儲中(表面上看是為了更輕松地進行搜索),但是它們對于當前形式的ElasticSearch來說是完美的。
因此,想象一下一個充滿啤酒配方的ElasticSearch索引,因為……嗯……我喜歡釀造啤酒(也喝啤酒)。
首先,我將使用Node的ElasticSearch Client將一些啤酒配方添加到ElasticSearch中(請注意,代碼雖然是CoffeeScript )。 我將這些啤酒配方添加到beer_recipes索引中,如下所示:
添加啤酒食譜
beer_1 = {name: "Todd Enders' Witbier",style: "wit, Belgian ale, wheat beer",ingredients: "4.0 lbs Belgian pils malt, 4.0 lbs raw soft red winter wheat, 0.5 lbs rolled oats, 0.75 oz coriander, freshly ground Zest from two table oranges and two lemons, 1.0 oz 3.1% AA Saaz, 3/4 corn sugar for priming, Hoegaarden strain yeast" }client.index('beer_recipes', 'beer', beer_1).on('data', (data) ->console.log(data) ).exec()請注意,如何在ingredients字段中找到食譜JSON文檔的有趣部分,即beer_1 。 該字段基本上是一大串有價值的文本(您可以想象此字符串本質上是電子郵件的正文)。 因此,盡管ingredients字段是非結構化的,但人們顯然仍希望進行搜索。
我將再添加一個食譜以達到良好的效果:
添加第二份啤酒食譜
beer_2 = {name: "Wit",style: "wit, Belgian ale, wheat beer",ingredients: "4 lbs DeWulf-Cosyns 'Pils' malt, 3 lbs brewers' flaked wheat (inauthentic; will try raw wheat nest time), 6 oz rolled oats, 1 oz Saaz hops (3.3% AA), 0.75 oz bitter (Curacao) orange peel quarters (dried), 1 oz sweet orange peel (dried), 0.75 oz coriander (cracked), 0.75 oz anise seed, one small pinch cumin, 0.75 cup corn sugar (priming), 10 ml 88% food-grade lactic acid (at bottling), BrewTek 'Belgian Wheat' yeast" }client.index('beer_recipes', 'beer', beer_2).on('data', (data) ->console.log(data) ).exec()這是一個炎熱的夏日,我想我想用檸檬作為原料制作啤酒(要清楚:我想用檸檬皮(它是由檸檬皮制成的))。 因此,自然地,我需要查找(即搜索 )其中含有檸檬的食譜。
因此,我將在索引中搜索包含“檸檬”一詞的食譜,如下所示:
尋找檸檬
query = { "query" : { "term" : { "ingredients" : "lemon" } } }client.search('beer_recipes', 'beer', query).on('data', (data) ->data = JSON.parse(data)for doc in data.hits.hitsconsole.log doc._source.styleconsole.log doc._source.nameconsole.log doc._source.ingredients ).exec()但是什么都沒有顯示-沒有結果! 這是為什么?
如果仔細查看前面的代碼示例(具體來說是beer_1 JSON文檔),您會發現文本中有“檸檬”一詞(即“……兩個橙子和兩個檸檬……”)。 事實證明,默認情況下,ElasticSearch索引值的方式, 檸檬不一定要匹配- 檸檬卻可以。
尋找檸檬
query = { "query" : { "term" : { "ingredients" : "lemons" } } }client.search('beer_recipes', 'beer', query).on('data', (data) ->data = JSON.parse(data)for doc in data.hits.hitsconsole.log doc._source.styleconsole.log doc._source.nameconsole.log doc._source.ingredients ).exec()瞧,此搜索返回了成功! 但這至少是不便的。 基本上, ingredients字段中的單詞按原樣標記。 因此,搜索“檸檬”有效,而“檸檬”無效。 注意:有多種搜索機制,對“ lemon *”的搜索應已返回結果。
將文檔添加到ElasticSearch索引后,將分析其字段并將其轉換為tokens 。 對索引執行搜索時,將對這些標記進行搜索。 ElasticSearch如何標記文檔是可以配置的。
可以使用不同的ElasticSearch分析器-從允許您支持非英語語言搜索的語言分析器到雪球分析器,后者將一個單詞轉換為其詞根(或詞干,并且從詞創建詞干的過程稱為詞干 ),產生一個更簡單的令牌。 例如,“檸檬”雪球將是“檸檬”。 或者,如果在經過雪球分析的文檔中有“敲門”和“敲門”一詞,則這兩個詞都將以“敲門”為詞干。
您可以通過索引映射API更改文檔的標記方式,如下所示:
使用cURL更改索引的映射
curl -XPUT 'http://localhost:9200/beer_recipes' -d '{ "mappings" : {"beer" : {"properties" : {"ingredients" : { "type" : "string", "analyzer" : "snowball" }}}} }'請注意,以上映射如何指定將通過雪球分析器分析ingredients字段。 另請注意, 在開始向其中添加文檔之前 ,必須更改索引的映射! 因此,在這種情況下,我需要刪除索引,運行上面的映射調用,然后重新添加這兩個配方。
現在,我可以開始在配方中搜索“檸檬”或“檸檬”成分。
現在搜索檸檬有效!
query = { "query" : { "term" : { "ingredients" : "lemon" } } }client.search('beer_recipes', 'beer', query).on('data', (data) ->data = JSON.parse(data)for doc in data.hits.hitsconsole.log doc._source.styleconsole.log doc._source.nameconsole.log doc._source.ingredients ).exec()請記住, 滾雪球可能會無意間使搜索結果的相關性降低 。 可以將長詞變成更常見但完全不同的詞。 例如,如果您將包含單詞“ sextant”的文檔滾雪球,則單詞“ sex”將作為詞干。 因此,搜索“ sextant”也將返回包含單詞“ sex”的文檔(反之亦然)。
ElasticSearch為您提供了強大的搜索引擎; 另外,略微考慮了如何分析文檔的內容,您將使搜索事件更加相關。
翻譯自: https://www.javacodegeeks.com/2013/09/understanding-elasticsearch-analyzers.html
總結
以上是生活随笔為你收集整理的了解ElasticSearch分析器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDK 8中几乎命名的方法参数
- 下一篇: 红粉骷髅什么意思 红粉骷髅怎么理解