ElasticSearch analyzed fields

落爺英雄遲暮 提交于 2019-12-24 11:58:27

问题


I'm building my search but need to analyze 1 field with different analyzers. My problem is for a field I need to have an analyzer on it for stemming (snowball) and then also one to keep the full word as one token (keyword). I can get this to work by the following index settings:

curl -X PUT "http://localhost:9200/$IndexName/" -d '{
    "settings":{
        "analysis":{
            "analyzer":{
                "analyzer1":{
                    "type":"custom",
                    "tokenizer":"keyword",
                    "filter":[ "standard", "lowercase", "stop", "snowball", "my_synonyms" ]
                }
            }
        },
        "filter": {
          "my_synonyms": {
           "type": "synonym",
           "synonyms_path ": "synonyms.txt"
          }
        }
      }
    },
    "mappings": {
        "product": {
            "properties": {
                "title": {
                    "type": "string",
                    "search_analyzer" : "analyzer1",
                    "index_analyzer" : "analyzer1"
                }
            }
        }
    }
}';

The problem comes when searching on a single word in the title field. If it's populated with The Cat in the Hat it will store it as "The Cat in the Hat" but if I search for cats I get nothing returned.

Is this even possible to accomplish or do I need to have 2 separate fields and analyze one with keyword and the other with snowball?

I'm using nest in vb code to index the data if that matters.

Thanks Robert


回答1:


You can apply two different analyzers to the same using the fields property (previously known as multi fields).

My VB.NET is a bit rusty, so I hope you don't mind the C# examples. If you're using the latest code from the dev branch, Fields was just added to each core mapping descriptor so you can now do this:

client.Map<Foo>(m => m
    .Properties(props => props
        .String(s => s
            .Name(o => o.Bar)
            .Analyzer("keyword")
            .Fields(fs => fs
                .String(f => f
                    .Name(o => o.Bar.Suffix("stemmed"))
                    .Analyzer("snowball")
                )
            )
        )
    )
);

Otherwise, if you're using NEST 1.0.2 or earlier (which you likely are), you have to accomplish this via the older multi field type way:

client.Map<Foo>(m => m
    .Properties(props => props
        .MultiField(mf => mf
            .Name(o => o.Bar)
            .Fields(fs => fs
                .String(s => s
                    .Name(o => o.Bar)
                    .Analyzer("keyword"))
                .String(s => s
                    .Name(o => o.Bar.Suffix("stemmed"))
                    .Analyzer("snowball"))
            )
        )
    )
);

Both ways are supported by Elasticsearch and will do the exact same thing. Applying the keyword analyzer to the primary bar field, and the snowball analyzer to the bar.stemmed field. stemmed of course was just the suffix I chose in these examples, you can use whatever suffix name you desire. In fact, you don't need to add a suffix, you can name the multi field something completely different than the primary field.



来源:https://stackoverflow.com/questions/25432661/elasticsearch-analyzed-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!