弹性搜索中特殊字符的处理

时间:2014-11-22 18:02:25

标签: elasticsearch

我使用以下分析器:

curl -XPUT 'http://localhost:9200/sample/' -d '
{
  "settings" : {
  "index": {
    "analysis": {
      "analyzer": {
        "default": {
         "type": "custom",
         "tokenizer": "keyword",
         "filter": ["trim", "lowercase"]}
      }
    }
  }
  }
}'

然后,当我尝试插入一些包含%等特殊字符的文档时,它会转换为十六进制。

1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8 - >实际值

1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8 

- >储值。

样品:

curl -XPUT 'http://localhost:9200/sample/strom/1' -d '{
    "user" : "user1",
    "message" : "1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8"
}'

只有在数据超过数百万份文档后才会出现问题。早些时候它用它存储它。

现在,如果我尝试使用搜索,

1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8

无法检索文档。我该如何处理?在将特殊字符转换为十六进制时,该行为似乎是不确定的。

我无法在localmachine上复制相同的问题。

有人可以解释我所犯的错误吗?

1 个答案:

答案 0 :(得分:1)

curl -XGET localhost:9200/_analyze?tokenizer=keyword\&filters=trim,lowercase\&pretty -d '1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8'
{
  "tokens" : [ {
    "token" : "1%2fpjjp3jv2c24idfeu9xphbayxxh%2fdhtbmchb35sdznxo2g8vz4d7gtivy54imix_149c95f02a8",
    "start_offset" : 0,
    "end_offset" : 80,
    "type" : "word",
    "position" : 1
  } ]
}

读取上面的分析器输出,在给出分析器的情况下,您的示例文本将转换为单个小写但其他方面相同的标记。你确定没有角色过滤器吗?那就是HTML编码。

您应该能够以:

运行它
curl -XGET localhost:9200/sample/_analyze?field=message' -d 'text to analyze'

由于它不是直接用分析仪再现,我试图通过创建一个索引来测试它来重现这个:

curl -XPUT localhost:9200/indexed-analysis -d '
{
  "settings": {
    "number_of_shards" : 1,
    "number_of_replicas" : 0,
    "index": {
      "analysis": {
        "analyzer": {
          "default": {
           "type": "custom",
           "tokenizer": "keyword",
           "filter": ["trim", "lowercase"]
          }
        }
      }
    }
  }, 
  "mappings": {
    "indexed" : {
      "properties": {
        "text" : { "type" : "string" }
      }
    }
  }
}'

curl -XPUT localhost:9200/indexed-analysis/indexed/1 -d '{
  "text" :
    "1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8"
}'

curl -XGET localhost:9200/indexed-analysis/indexed/1?pretty

这产生了正确的,结果相同:

{
  "_index" : "indexed-analysis",
  "_type" : "indexed",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source":{
    "text" : "1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8"
  }
}

所以,我尝试了_search,我找到了它。

curl -XGET localhost:9200/indexed-analysis/_search -d '{
  "query": {
    "match": {
      "text": "1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8"
    }
  }
}'

结果:

{
   "took": 5,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.30685282,
      "hits": [
         {
            "_index": "indexed-analysis",
            "_type": "indexed",
            "_id": "1",
            "_score": 0.30685282,
            "_source": {
               "text": "1%2fPJJP3JV2C24iDfEu9XpHBaYxXh%2fdHTbmchB35SDznXO2g8Vz4D7GTIvY54iMiX_149c95f02a8"
            }
         }
      ]
   }
}

所有这些都导致了三种可能性:

  1. 您的搜索分析器与您的索引分析器不同。这几乎总会产生意想不到的结果。

    使用default会强制它用于读取和写入,但您可以/应该验证实际上是否正在使用(而不是default_indexdefault_search):< / p>

    • curl -XGET /sample/_settings
    • curl -XGET /sample/_mapping

    如果您在message字段的映射中看到正在配置分析器,那么这应该是一个红旗。

  2. 你有一个字符过滤器搞乱索引字符串(它可能不会对你的搜索字符串做同样的事情,因此指向#1)。

  3. 您正在使用的Elasticsearch版本中存在一个错误(希望不是,但您永远不知道)。以上所有测试都是针对1.3.2版本完成的。