如何在 ElasticSearch 中基于正则表达式过滤令牌

2024-04-02

对于 ElasticSearch 查询,我们希望以不同的方式处理单词(即仅由字母组成的标记)和非单词。为此,我们尝试定义两个分析器,返回单词或非单词。

例如,我们有描述五金店产品的文档:

{
    "name": "Torx drive T9",
    "category": "screws",
    "size": 2.5,
}

然后,用户将搜索“Torx T9”并期望找到此文档。搜索 T9 会过于通用,并且会提供太多不相关的产品。因此,如果我们已经找到“Torx”,我们只想搜索“T9”术语。

我们尝试创建一个这样的查询

{
    "query": {
        "bool": {
            "must": {
                "match: {
                    "name": {
                    "query": "Torx T9",
                    "analyzer": "words"
                 }
             },
            "should": {
                "match: {
                    "name": {
                    "query": "Torx T9",
                    "analyzer": "nonwords"
                 }
             }
         }
     }
}

这个想法是创建令牌过滤器来完成此操作会很简单。例如:

"settings": {
  "analysis": {
     "filter": {
        "words": {
           "type": "pattern",
           "pattern": "\\A\\p{L}*\\Z",
        },
        "nonwords": {
            "type": "pattern",
            "pattern": "\\P{L}",
        }
    }
}

但似乎没有一个过滤器只是匹配模式。相反,我们(ab)使用pattern_replace过滤器:

"settings": {
  "analysis": {
     "filter": {
        "words": {
           "type": "pattern_replace",
           "pattern": "\\A((?=.*\\P{L}).*)",
           "replacement": ""
        },
        "nonwords": {
            "type": "pattern_replace",
            "pattern": "\\A((?!.*\\P{L}).*)",
            "replacement": ""
        },
        "nonempty": {
            "type": "length",
            "min":1
        }
    }
}

这会将不需要的标记替换为空标记,然后可以通过非空过滤器将其删除。这似乎可行,但所需的模式更加模糊。

有没有更好的方式来表达这一点?


你可以试试查询字符串查询 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html根据您的要求,default_operator 为“AND”。

例如,考虑您正在索引两个字符串“Torxdrive T9”和“SquaredriveT9”。如果您使用空白分词器 https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-whitespace-tokenizer.html对于索引,字符串将被分析为以下标记

第一个文件:torx, drive and t9.
第二份文件:square, drive and t9.

然后使用查询字符串查询与默认运算符 AND 匹配文档将产生预期结果。

样本映射

{
  "settings": {
    "analysis": {
      "analyzer": {
        "whitespace": {
          "type": "pattern",
          "pattern": "\\s+"
        }
      }
    }
  },
  "mappings": {
    "my_type": {
      "properties": {
        "name": {
          "type": "string",
          "analyzer": "whitespace"
        }
      }
    }
  }
}

示例查询

{
   "query": {
    "query_string": {
       "default_field": "name",
       "query": "Torx T9",
       "default_operator": "AND"
        }
     }
 }

仅当两者都满足时此查询才会产生结果torx and t9文档中给出。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 ElasticSearch 中基于正则表达式过滤令牌 的相关文章

随机推荐