Elasticsearch针对单个字段的多个分析器

时间:2015-06-19 16:40:36

标签: indexing elasticsearch

我使用严格的预定义映射将不同类型的文档存储在单个索引中。所有这些都有一些字段(比如“body”),但我希望在索引时对它们进行略微不同的分析(例如,对特定文档使用不同的标记过滤器),并在搜索时以相同的方式进行处理。据我所知,每个文档都无法指定分析器。

我还考虑使用:

  1. 对象字段具有不同分析的文档类型的子字段,因此每个文档只有一个填充的子字段(例如,“body.mail”,“body.html”)。问题是我无法搜索整个“正文”字段,该字段将查看其所有子字段(不破坏现有应用程序)。
  2. 多字段的新转世(具有通用分析器的“body”字段,并在其中定期分析“mail”,“html”等)。 Hovewer,我不确定是否可以在索引时直接使用它们并在搜索时间接使用它们(例如,使用{"mail":"smth"}保存对象以使用特定的索引分析器,然后按"query":{"body":"smth"}搜索以使用泛型搜索分析器)。
  3. 要将“正文”分隔为具有不同映射的多个字段,请将其从_all中删除,然后将copy_to设置为单个body字段。我不确定,但由于复制,它会增加大量的索引开销。

2 个答案:

答案 0 :(得分:14)

正如我在评论中所提到的,你想要的是不可能的。您的要求在一个句子中是:以多种方式分析相同的数据,但搜索为单个字段,因为这会破坏现有的应用程序。

             -- body.html          
             -- body.email
body field ---- body.content     --- all searched as "body"
            ...
             -- body.destination
             -- body.whatever
  • 您的第一个选项是多字段,其具有以下确切目的:以多种方式分析相同的数据。问题是您无法搜索"body"并期望ES搜索body.htmlbody.email ...即使可能,您也希望使用不同的分析器进行搜索。再一次,不可能。此选项要求您更改应用,并在multi_matchquery_string中搜索每个字段。

  • 您的第二个选项 - reincarnation of multi-fields - 将再次无效,因为您无法在后台引用body和ES来匹配mail,{{ 1}} 等。

  • 第三个选项 - 使用content - 将无效,因为复制到另一个字段" X"意味着索引正在复制的数据将使用copy_to分析器进行分析,这样就无法对分析相同数据进行分析。

  • 可能有第四个选项 - "path": "just_name" from multi_fields - 初看它应该有效。意思是,你可以拥有3个多字段(电子邮件,内容,html),这三个字段都有X个子字段。使用body即使"path": "just_name"是多个其他字段的子字段,您也只能搜索body。但这是不可能的,因为这种类型的多字段不会接受同一body 的不同分析器。

无论哪种方式,您都需要更改您的要求中的某些内容,因为它们无法按照您的需要进行操作。

话虽如此,我很想知道您在应用程序中使用了哪些查询。这将是一个简单的更改(是的,您需要更改您的应用)从查询body字段到查询body中的body.*

我还有另一个解决方案:为multi_match的每个分析器创建多个索引,一个索引。例如,对于bodymailcontent,您可以定义三个索引:

html

您会看到所有这些PUT /multi_fields1 { "mappings": { "test": { "properties": { "body": { "type": "string", "index_analyzer": "whitespace", "search_analyzer": "standard" } } } } } PUT /multi_fields2 { "mappings": { "test": { "properties": { "body": { "type": "string", "index_analyzer": "standard", "search_analyzer": "standard" } } } } } PUT /multi_fields3 { "mappings": { "test": { "properties": { "body": { "type": "string", "index_analyzer": "keyword", "search_analyzer": "standard" } } } } } 和相同的字段名称 - type - 但不同body。然后定义别名:

index_analyzer

将别名命名为与当前索引相同。应用程序不需要更改,它将使用相同的名称进行索引搜索,此名称不会指向索引,而是指向别名,而后者又指向您的多个索引。需要更改的是如何索引文档,因为POST _aliases { "actions": [ {"add": { "index": "multi_fields1", "alias": "multi"}}, {"add": { "index": "multi_fields2", "alias": "multi"}}, {"add": { "index": "multi_fields3", "alias": "multi"}} ] } 文档需要进入html索引,例如,multi_fields1文档需要在email索引中编入索引等

无论您找到/选择哪种解决方案,您的要求都需要改变,因为您无法实现所需的方式。

答案 1 :(得分:3)

我认为你可以使用多场。使用多字段,您可以为每个子字段定义分析器(索引和搜索),并根据应用程序要求在相应字段上进行搜索。 一般来说,索引分析器可以在场与场之间存在差异,对于搜索分析器也是如此。

{
  "your_type" : {   
    "properties":{
        "body" : {
            "type" : "string",
            "index" : "analyzed",
            "index_analyzer" : "index_body_analyzer",
            "search_analyzer" : "search_body_analyzer",
            "fields" : {
                "mail" : {
                    "type" : "string",
                    "index" : "analyzed",
                    "index_analyzer" : "index_bodymail_analyzer",
                    "search_analyzer" : "search_bodymail_analyzer"
                },
                "html": {
                    "type" : "string",              
                    "index" : "analyzed",
                    "index_analyzer" : "index_bodyhtml_analyzer",
                    "search_analyzer" : "search_bodyhtml_analyzer"
                }
            }
        }
    }
}