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

Yuu*_*uri 9 indexing elasticsearch

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

我还考虑使用的内容:

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

And*_*fan 14

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

             -- body.html          
             -- body.email
body field ---- body.content     --- all searched as "body"
            ...
             -- body.destination
             -- body.whatever
Run Code Online (Sandbox Code Playgroud)
  • 您的第一个选项是多字段,其具有以下确切目的:以多种方式分析相同的数据.问题是你不能搜索"body"并期望ES搜索body.html,body.email...即使这是可能的,你也希望用不同的分析器进行搜索.再一次,不可能.此选项要求您更改应用程序并搜索a multi_match或a中的每个字段query_string.

  • 你的第二个选项- reincarnation of multi-fields-将再次无法工作,因为你不能引用body和ES,在后台,匹配mail,content等等.

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

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

无论哪种方式,您需要更改您的要求中的某些内容,因为它们无法按您希望的方式工作.


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

我还有另一个解决方案:创建多个索引,为每个分析器创建一个索引body.例如,对于mail,contenthtml定义三个指标:

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"
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

你看到它们都有相同type和相同的字段名称body- 但不同的index_analyzers.然后定义一个别名:

POST _aliases
{
  "actions": [
    {"add": {
        "index": "multi_fields1",
        "alias": "multi"}},
    {"add": {
        "index": "multi_fields2",
        "alias": "multi"}},
    {"add": {
        "index": "multi_fields3",
        "alias": "multi"}}
  ]
}
Run Code Online (Sandbox Code Playgroud)

将别名命名为与当前索引相同.应用程序不需要更改,它将使用相同的名称进行索引搜索,此名称不会指向索引,而是指向别名,而别名又指向多个索引.需要改变的是如何索引文档,因为html文档需要以multi_fields1索引为例,email文档需要索引multi_fields2索引等.

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


Duc*_*ong 5

我认为你可以使用多字段。通过多字段,您可以为每个子字段定义分析器(索引和搜索),并根据应用程序需求对相应字段进行搜索。一般来说,索引分析器可以根据字段的不同而有所不同,搜索分析器也是如此。

{
  “你的类型”:{   
    “特性”:{
        “身体” : {
            “类型”:“字符串”,
            “索引”:“分析”,
            "index_analyzer" : "index_body_analyzer",
            "search_analyzer": "search_body_analyzer",
            “字段”:{
                “邮件” : {
                    “类型”:“字符串”,
                    “索引”:“分析”,
                    "index_analyzer": "index_bodymail_analyzer",
                    “search_analyzer”:“search_bodymail_analyzer”
                },
                “html”:{
                    “类型”:“字符串”,              
                    “索引”:“分析”,
                    "index_analyzer": "index_bodyhtml_analyzer",
                    “search_analyzer”:“search_bodyhtml_analyzer”
                }
            }
        }
    }
}