ElasticSearch - 返回查询的facet的完整值

时间:2014-01-27 15:34:10

标签: lucene elasticsearch

我最近开始使用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”选项没有这样做,它只限制了上面的子集。

  • 我必须配置这个full_name facet“如何工作”
  • 我必须为当前查询添加一些选项
  • 我必须做一些“映射”(目前非常模糊)

由于

2 个答案:

答案 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
      }
   ]
}