elasticsearch,Indexing,elasticsearch" /> elasticsearch,Indexing,elasticsearch" />

Indexing Elasticsearch针对单个字段搜索多个分析器

Indexing Elasticsearch针对单个字段搜索多个分析器,indexing,elasticsearch,Indexing,elasticsearch,我使用严格的预定义映射将不同类型的文档存储在单个索引中。它们都有一些字段(比如“body”),但我希望在索引时对它们进行稍微不同的分析(例如,对特定文档使用不同的标记过滤器),并在搜索时以相同的方式进行处理。据我所知,不能在每个文档中指定分析器 我还考虑使用: 对象字段具有针对文档类型的不同分析子字段,因此每个文档只有一个填充子字段(如“body.mail”、“body.html”)。问题是,我无法搜索整个“body”字段,该字段将查看其所有子字段(以不破坏现有应用程序) 多字段的新转世(将“b

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

我还考虑使用:

  • 对象字段具有针对文档类型的不同分析子字段,因此每个文档只有一个填充子字段(如“body.mail”、“body.html”)。问题是,我无法搜索整个“body”字段,该字段将查看其所有子字段(以不破坏现有应用程序)
  • 多字段的新转世(将“body”字段与通用分析器一起使用,并且仅在其中分析“mail”、“html”等)。Hovewer,我不确定是否可以在索引时直接使用它们,在搜索时间接使用它们(例如,使用
    {“mail”:“smth”}
    保存对象以使用特定的索引分析器,然后通过
    “query”:{“body”:“smth”}
    搜索以使用通用搜索分析器)

  • 要将“body”分隔为具有不同映射的多个字段,请将它们从
    \u all
    中删除,并将
    copy\u To
    设置为单个
    body
    字段。我不确定,但它会因为复制而增加大量的索引开销

  • 我认为你可以使用多字段。使用multi-field,您可以为每个子字段定义分析器(索引和搜索),并根据应用程序要求对相应字段进行搜索。 通常,索引分析器在不同的字段中可能有所不同,搜索分析器也是如此

    { "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" } } } } } { “您的_类型”:{ “财产”:{ “正文”:{ “类型”:“字符串”, “索引”:“已分析”, “索引分析器”:“索引体分析器”, “搜索分析器”:“搜索分析器”, “字段”:{ “邮件”:{ “类型”:“字符串”, “索引”:“已分析”, “索引邮件分析器”:“索引邮件分析器”, “搜索邮件分析器”:“搜索邮件分析器” }, “html”:{ “类型”:“字符串”, “索引”:“已分析”, “索引分析器”:“索引分析器”, “搜索分析器”:“搜索分析器” } } } }
    } 正如我在评论中提到的,您想要的是不可能的。您的要求是:以多种方式分析相同的数据,但作为单个字段进行搜索,因为这将破坏现有的应用程序

                 -- body.html          
                 -- body.email
    body field ---- body.content     --- all searched as "body"
                ...
                 -- body.destination
                 -- body.whatever
    
    • 您的第一个选择是多字段,它有一个确切的目的:以多种方式分析相同的数据。问题是您无法搜索
      “body”
      并期望ES搜索
      body.html
      body.email
      …即使这是可能的,您也希望使用不同的分析器进行搜索。同样,这是不可能的。此选项要求您更改应用程序并在
      多匹配
      查询字符串
      中搜索每个字段
    • 您的第二个选项——
      多字段转世
      ——将再次无效,因为您无法在后台引用
      正文
      和ES来匹配
      邮件
      内容

    • 第三个选项-使用
      copy_to
      -将不起作用,因为复制到另一个字段“X”意味着将使用
      X
      的分析器对复制的数据进行索引分析,这打破了对相同数据进行不同分析的要求

    • 可能还有第四个选项——乍一看应该是可行的。也就是说,你可以有三个多字段(电子邮件、内容、html),这三个字段都有一个
      正文
      子字段。有
      路径:“只是名称”
      允许您仅搜索
      正文
      ,即使
      正文
      是多个其他字段的子字段。但这是不可能的,因为这种类型的多字段不会为同一
      正文
      接受不同的分析器

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


    话虽如此,我很想知道你在应用程序中使用了什么查询。这将是一个简单的更改(是的,你需要更改你的应用程序),从查询
    body
    字段改为查询
    body.
    多重匹配中

    我还有另一个解决方案:创建多个索引,为
    正文
    的每个分析器创建一个索引。例如,对于
    邮件
    内容
    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"
            }
          }
        }
      }
    }
    
    您可以看到,它们都具有相同的
    类型
    和相同的字段名-
    正文
    ,但不同的
    索引分析器
    s。然后定义一个别名:

    POST _aliases
    {
      "actions": [
        {"add": {
            "index": "multi_fields1",
            "alias": "multi"}},
        {"add": {
            "index": "multi_fields2",
            "alias": "multi"}},
        {"add": {
            "index": "multi_fields3",
            "alias": "multi"}}
      ]
    }
    
    将别名命名为与当前索引相同的名称。应用程序不需要更改,它将使用相同的名称进行索引搜索,此名称不会指向索引,而是指向一个别名,该别名反过来引用多个索引。需要更改的是如何为文档编制索引,因为
    html
    documents n需要进入
    多字段1
    索引例如,一封
    电子邮件
    文档需要在
    多字段2
    索引等中进行索引


    无论您找到/选择什么解决方案,您的需求都需要更改,因为您想要的方式是不可能的。

    为什么不为不同的字段(如“邮件”、“html”等)编制索引,为每个字段使用不同的分析器,并使用多匹配查询来搜索所有这些字段?我认为,这些