我最近开始使用ElasticSearch。我尝试完成一些用例。我有一个问题。
我已将一些用户的全名编入索引(例如“Jean-Paul Gautier”,“Jean De La Fontaine”)。
我尝试让所有全名响应某些查询。
例如,我希望100个最常用的全名由“J”开始
{
"query": {
"query_string" : { "query": "full_name:J*" } }
},
"facets":{
"name":{
"terms":{
"field": "full_name",
"size":100
}
}
}
}
我得到的结果是全名:“Jean”,“Paul”,“Gautier”,“De”,“La”,“Fontaine”。
如何获得“Jean-Paul Gautier”和“Jean De La Fontaine”(所有full_name值由'J'乞讨)? “post_filter”选项没有这样做,它只限制了上面的子集。
由于
答案 0 :(得分:13)
您只需在字段上设置"index": "not_analyzed"
,就可以在您的方面获取完整的,未经修改的字段值。
通常情况下,有一个版本的字段未分析(用于分面)而另一个版本(用于搜索)是很好的。 "multi_field"
字段类型对此非常有用。
所以在这种情况下,我可以按如下方式定义映射:
curl -XPUT "http://localhost:9200/test_index/" -d'
{
"mappings": {
"people": {
"properties": {
"full_name": {
"type": "multi_field",
"fields": {
"untouched": {
"type": "string",
"index": "not_analyzed"
},
"full_name": {
"type": "string"
}
}
}
}
}
}
}'
这里我们有两个子字段。与父名称相同的名称将是默认名称,因此如果您搜索"full_name"
字段,Elasticsearch将实际使用"full_name.full_name"
。 "full_name.untouched"
会为您提供所需的方面结果。
接下来我添加两个文档:
curl -XPUT "http://localhost:9200/test_index/people/1" -d'
{
"full_name": "Jean-Paul Gautier"
}'
curl -XPUT "http://localhost:9200/test_index/people/2" -d'
{
"full_name": "Jean De La Fontaine"
}'
然后我可以在每个字段上查看返回的内容:
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
"size": 0,
"facets": {
"name_terms": {
"terms": {
"field": "full_name"
}
},
"name_untouched": {
"terms": {
"field": "full_name.untouched",
"size": 100
}
}
}
}'
我回过头来看:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0,
"hits": []
},
"facets": {
"name_terms": {
"_type": "terms",
"missing": 0,
"total": 7,
"other": 0,
"terms": [
{
"term": "jean",
"count": 2
},
{
"term": "paul",
"count": 1
},
{
"term": "la",
"count": 1
},
{
"term": "gautier",
"count": 1
},
{
"term": "fontaine",
"count": 1
},
{
"term": "de",
"count": 1
}
]
},
"name_untouched": {
"_type": "terms",
"missing": 0,
"total": 2,
"other": 0,
"terms": [
{
"term": "Jean-Paul Gautier",
"count": 1
},
{
"term": "Jean De La Fontaine",
"count": 1
}
]
}
}
}
如您所见,分析字段返回单字,低字符标记(当您未指定分析器时,使用standard analyzer),未分析的子字段返回未修改的原始文本。
这是一个可以玩的可运行示例: http://sense.qbox.io/gist/7abc063e2611846011dd874648fd1b77450b19a5
答案 1 :(得分:2)
尝试更改“full_name”的映射:
"properties": {
"full_name": {
"type": "string",
"index": "not_analyzed"
}
...
}
not_analyzed
意味着它将保持原样,大写字母,空格,短划线等,这样“Jean De La Fontaine”将保持可查,而不会被标记为“Jean”“De”“La”“方丹“
你可以experiment with different analyzers using the api
注意标准部件对多部件名称的作用:
GET /_analyze?analyzer=standard
{'Jean Claude Van Dame'}
{
"tokens": [
{
"token": "jean",
"start_offset": 2,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "claude",
"start_offset": 7,
"end_offset": 13,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "van",
"start_offset": 14,
"end_offset": 17,
"type": "<ALPHANUM>",
"position": 3
},
{
"token": "dame",
"start_offset": 18,
"end_offset": 22,
"type": "<ALPHANUM>",
"position": 4
}
]
}