【问题标题】:Pattern Capture not working for forward slash模式捕获不适用于正斜杠
【发布时间】:2021-05-07 21:10:40
【问题描述】:

我在这样的记录中有一个字段:

{ 
  ....

  "test_field": "/xyz/abc-2021abs/drf/2021ABC"

  ....
}

pattern_capture 的帮助下,我正在创建一个不忽略正斜杠 (/) 的分析器。

这是我的映射和分析器。

{
    "mappings": {
      "properties": {
        "test_field": {
          "type": "text",
          "analyzer": "test_field_analyzer",
          "fields": {
            "exact": {
              "type": "keyword"
            }
          }
        }
      }
    },
    "settings": {
      "analysis": {
        "analyzer": {
          "test_field_analyzer": {
            "tokenizer" : "pattern",
            "filter" : [ "test_filter"]
          }
        },
        "filter" : {
            "test_filter" : {
               "type" : "pattern_capture",
               "preserve_original" : true,
               "patterns" : ["(\\p{Punct}+\\p{Alnum})"]
            }
         }
      }
    }
  }

当我检查生成的令牌时,正斜杠 (/) 被忽略,并且模式捕获的工作方式似乎与 pattern_capture 上的示例不同。

请让我知道我哪里做错了。

【问题讨论】:

    标签: elasticsearch indexing


    【解决方案1】:

    我不确定那些类似于 java 的 \\p 模式,但是这个

    {
      "mappings": {
        "properties": {
          "test_field": {
            "type": "text",
            "analyzer": "test_field_analyzer",
            "fields": {
              "exact": {
                "type": "keyword"
              }
            }
          }
        }
      },
      "settings": {
        "analysis": {
          "analyzer": {
            "test_field_analyzer": {
              "tokenizer": "keyword",
              "filter": [
                "test_filter"
              ]
            }
          },
          "filter": {
            "test_filter": {
              "type": "pattern_capture",
              "preserve_original": false,
              "patterns": [
                "(/[a-zA-Z-_0-9]+)"
              ]
            }
          }
        }
      }
    }
    

    将测试字段标记为

    ["/xyz", "/abc-2021abs", "/drf", "/2021ABC"]
    

    如果这就是你所追求的......

    编辑

    使用自定义模式tokenizer而不是pattern_capture 过滤器,还有一种更简单的方法:

    {
      "mappings": {
        "properties": {
          "test_field": {
            "type": "text",
            "analyzer": "test_field_analyzer",
            "fields": {
              "exact": {
                "type": "keyword"
              }
            }
          }
        }
      },
      "settings": {
        "analysis": {
          "analyzer": {
            "test_field_analyzer": {
              "type": "custom",
              "tokenizer": "my_pattern_tokenizer"
            }
          },
          "tokenizer": {
            "my_pattern_tokenizer": {
              "type": "pattern",
              "pattern": "(/[a-zA-Z-_0-9]+)",
              "group": 1
            }
          }
        }
      }
    }
    

    由于您正在处理路径,您可能会发现path hierarchy tokenizer 也很有用:

    {
      "mappings": {
        "properties": {
          "test_field": {
            "type": "text",
            "analyzer": "test_field_analyzer",
            "fields": {
              "exact": {
                "type": "keyword"
              }
            }
          }
        }
      },
      "settings": {
        "analysis": {
          "analyzer": {
            "test_field_analyzer": {
              "tokenizer": "path_hierarchy"
            }
          }
        }
      }
    }
    

    会产生

    ["/xyz", "/xyz/abc-2021abs", "/xyz/abc-2021abs/drf", "/xyz/abc-2021abs/drf/2021ABC"]
    

    【讨论】:

    • 我从第一个中得到了我期待的令牌。对于类似 java 的 \\p 模式,docs 表示:模式捕获令牌过滤器使用 Java Regular Expressions。为什么"tokenizer": "keyword" 工作而不是"tokenizer": "pattern_capture"
    • 我了解了\\p 模式的要点,但我对它们并不太熟悉——这就是我选择标准正则表达式的原因。至于为什么pattern_capture 不起作用——(\\p{Punct}+\\p{Alnum}) 只会匹配 1 个字符,而不是组中的多个字符。检查我的答案 EDIT 以进一步简化。
    猜你喜欢
    • 1970-01-01
    • 2013-01-22
    • 2019-03-20
    • 2018-07-21
    • 2012-04-27
    • 2016-08-23
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    相关资源
    最近更新 更多