在Elasticsearch中搜索已取消的文本

时间:2015-12-02 06:15:50

标签: elasticsearch elasticsearch-mapping

我在elasticsearch中存储了“付款参考号”。

它的布局是:2-4-3-6358445698191095312-4-2-635844533758635433

我希望能够通过

按付款参考编号搜索文件
  1. 使用“整体”参考编号进行搜索,例如放入2-4-2-635844533758635433
  2. “开始”中参考编号的任何“部分”。例如。 2-4-2-63(..所以只返回示例中的第二个)
  3. 注意:我不想搜索“中间”或“结尾”等。仅从头开始。

    无论如何,连字符让我感到困惑。

    问题

    1)我不确定是否应该在

    这样的映射中删除它们
    "char_filter" : {
        "removeHyphen" : {
            "type" : "mapping",
                "mappings" : ["-=>"]
            }
        },
    
    是不是。我从来没有以这种方式使用映射,所以不确定是否有必要。

    2)我想我需要一个'ngrams'过滤器,因为我希望能够从存在中搜索参考号的一部分。我觉得像

    "partial_word":{
        "filter":[
            "standard",
                "lowercase",
                "name_ngrams"
            ],
        "type":"custom",
        "tokenizer":"whitespace"
    },
    

    和过滤器

    "name_ngrams":{
        "side":"front",
            "max_gram":50,
            "min_gram":2,
        "type":"edgeNGram"
    },
    

    我不知道怎么把它们放在一起但是

    "paymentReference":{
        "type":"string",
        "analyzer": "??",
        "fields":{
            "partial":{
                "search_analyzer":"???",
                "index_analyzer":"partial_word",
                "type":"string"
            }
        }
    }
    

    我尝试的所有内容似乎总是在第二个搜索案例中“破解”。

    如果我'localhost:9200/orders/_analyze?field=paymentReference&pretty=1' -d "2-4-2-635844533758635433",它总是打破连字符,因为它是自己的令牌并返回例如所有2-的文件都是'很多'!而不是我在搜索2-4-2-6

    时想要的东西

    有人可以告诉我如何将这个字段映射到我想要实现的两种搜索类型吗?

    更新 - 回答

    有效的是Val在下面说的。我只是稍微改变了映射,使分析器更加具体,而且我不需要索引主字符串,因为我只是查询部分。

    映射

    "paymentReference":{
        "type": "string",
        "index":"not_analyzed",
        "fields": {
            "partial": {
                "search_analyzer":"payment_ref",
                "index_analyzer":"payment_ref",
                "type":"string"
            }
        }
    }
    

    分析仪

    "payment_ref": {
        "type": "custom",
        "filter": [
            "lowercase",
            "name_ngrams"
        ],
        "tokenizer": "keyword"
    }
    

    过滤

    "name_ngrams":{
        "side":"front",
        "max_gram":50,
        "min_gram":2,
        "type":"edgeNGram"
    },
    

2 个答案:

答案 0 :(得分:0)

您不需要使用映射字符过滤器。

您使用Edge NGram令牌过滤器是在正确的轨道上,因为您只需要搜索前缀。我会使用keyword标记器来确保该术语作为一个整体。所以设置它的方式是这样的:

curl -XPUT localhost:9200/orders -d '{
  "settings": {
    "analysis": {
      "analyzer": {
        "partial_word": {
          "type": "custom",
          "filter": [
            "lowercase",
            "ngram_filter"
          ],
          "tokenizer": "keyword"
        }
      },
      "filter": {
        "ngram_filter": {
          "type": "edgeNGram",
          "min_gram": 2,
          "max_gram": 50
        }
      }
    }
  },
  "mappings": {
    "order": {
      "properties": {
        "paymentReference": {
          "type": "string",
          "fields": {
            "partial": {
              "analyzer": "partial_word",
              "type": "string"
            }
          }
        }
      }
    }
  }
}'

然后,您可以分析将在paymentReference.partial字段中编入索引的内容:

curl -XGET 'localhost:9205/payments/_analyze?field=paymentReference.partial&pretty=1' -d "2-4-2-635844533758635433"

你得到了你想要的,即所有前缀:

{
  "tokens" : [ {
    "token" : "2-",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2-",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2-6",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2-63",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2-635",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2-6358",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "2-4-2-63584",
    "start_offset" : 0,
    "end_offset" : 24,
    "type" : "word",
    "position" : 1
  }, {
  ...

最后,您可以搜索任何前缀:

curl -XGET localhost:9200/orders/order/_search?q=paymentReference.partial:2-4-3

答案 1 :(得分:0)

不确定通配符搜索是否符合您的需求。我定义自定义过滤器并设置preserve_original并生成数字部分false。以下是示例代码:

PUT test1
{
  "settings" : {
    "analysis" : {
      "analyzer" : {
        "myAnalyzer" : {
          "type" : "custom",
          "tokenizer" : "whitespace",
          "filter" : [ "dont_split_on_numerics" ]
        }
      },
      "filter" : {
        "dont_split_on_numerics" : {
          "type" : "word_delimiter",
          "preserve_original": true,
          "generate_number_parts" : false
        }
      }
    }
  },
  "mappings": {
    "type_one": {
      "properties": {
        "title": { 
          "type": "text",
          "analyzer": "standard" 
        }
      }
    },
    "type_two": {
      "properties": {
        "raw": { 
          "type": "text",
          "analyzer": "myAnalyzer" 
        }
      }
    }
  }
}

POST test1/type_two/1
{
  "raw": "2-345-6789" 
}

GET test1/type_two/_search
{
  "query": {
    "wildcard": {
      "raw": "2-345-67*" 
    }
  }
}