【问题标题】:How to index both a string and its reverse?如何索引字符串及其反向?
【发布时间】:2014-08-06 03:50:00
【问题描述】:

我正在寻找一种将字符串“abc123”分析为[“abc123”,“321cba”]的方法。我查看了reverse 令牌过滤器,但这只会让我得到 ["321cba"]。关于这个过滤器的文档非常稀少,仅说明

reverse 类型的令牌过滤器...只是反转每个令牌。”

(见http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/analysis-reverse-tokenfilter.html)。

我还尝试过使用keyword_repeat 过滤器,它为我提供了两个实例。我不知道这是否有用,但现在它所做的一切都颠倒了这两种情况。

如何使用reverse 令牌过滤器同时保留原始令牌?

我的分析仪:

{ "settings" : { "analysis" : {
    "analyzer" : {
        "phone" : {
             "type"         : "custom"
            ,"char_filter"  : ["strip_non_numeric"]
            ,"tokenizer"    : "keyword"
            ,"filter"       : ["standard", "keyword_repeat", "reverse"]
        }
    }
    ,"char_filter" : {
        "strip_non_numeric" : {
            "type" : "pattern_replace"
            ,"pattern" : "[^0-9]"
            ,"replacement" : ""
        }
    }
}}}

【问题讨论】:

  • 那么,你的问题解决了吗?
  • @progrrammer:我找到了一个可以接受(但丑陋得可怕)的解决方法。请参阅已接受的答案。请不要因为我滥用正则表达式而打我。 :-o

标签: filter elasticsearch token


【解决方案1】:

制作并放置一个分析器来反转字符串(比如 reverse_analyzer)。

PUT index_name
{
    "settings": {
        "analysis": {
            "analyzer": {
                "reverse_analyzer": {
                    "type": "custom",
                    "char_filter": [
                        "strip_non_numeric"
                    ],
                    "tokenizer": "keyword",
                    "filter": [
                        "standard",
                        "keyword_repeat",
                        "reverse"
                    ]
                }
            },
            "char_filter": {
                "strip_non_numeric": {
                    "type": "pattern_replace",
                    "pattern": "[^0-9]",
                    "replacement": ""
                }
            }
        }
    }
}

然后,对于一个字段,(比如 phoneno),使用映射 as,(创建一个类型并为 phone as 添加映射)

PUT index_name/type_name/_mapping
{
   "type_name": {
      "properties": {
         "phone_no": {
            "type": "string",
            "fields": {
               "reverse": {
                  "type": "string",
                  "analyzer": "reverse_analyzer"
               }
            }
         }
      }
   }
}

因此,phone_no 就像多字段一样,它将存储一个字符串及其反向, 如果你索引

phone_no: 911220

然后在elasticsearch中,会有字段为, phone_no: 911220 and phone_no.reverse : 022119,因此您可以搜索、过滤反向或未反向字段。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我不相信您可以直接执行此操作,因为我不知道有任何方法可以让反向令牌过滤器也输出原始内容。

    但是,您可以使用 fields 参数同时索引原始和反向,而无需额外编码。然后,您将搜索这两个字段。

    假设您的字段名为 phone_number:

    "phone_number": {
        "type": "string",
        "fields": {
            "reverse":   { "type": "string", "index": "phone" }
        }
    }
    

    在这种情况下,我们使用默认分析器(假设标准)进行索引,并使用您的客户分析器手机反向索引。然后,您针对这两个字段发出查询。

    http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/_multi_fields.html

    【讨论】:

      【解决方案3】:

      我不确定是否可以使用内置的令牌过滤器集来做到这一点。我建议您创建自己的plugin。有弹性搜索团队支持的ICU Analysis plugin,可以作为例子。

      【讨论】:

        【解决方案4】:

        我最终在分析器中使用了以下两个 char_filter。这是对正则表达式的丑陋滥用,但它似乎有效。它仅限于前 20 个数字字符,但在我的用例中是可以接受的。

        首先它将所有数字字符分组,然后使用自己的(仅限数字!)反向显式重建字符串。然后,替换模式中心的空间会导致分词器将其拆分为两个分词 - 原始的和反向的。

        ,"char_filter" : {
            "strip_non_numeric" : {
                "type" : "pattern_replace"
                ,"pattern" : "[^0-9]"
                ,"replacement" : ""
            }
            ,"dupe_and_reverse" : {
                "type" : "pattern_replace"
                ,"pattern" : "([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)([0-9]?)"
                ,"replacement" : "$1$2$3$4$5$6$7$8$9$10$11$12$13$14$15$16$17$18$19$20 $20$19$18$17$16$15$14$13$12$11$10$9$8$7$6$5$4$3$2$1"
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-07
          • 1970-01-01
          • 2021-11-19
          • 1970-01-01
          • 1970-01-01
          • 2021-01-21
          • 1970-01-01
          • 2012-04-16
          相关资源
          最近更新 更多