检查输入是否包含字段值作为子字符串

时间:2017-05-17 09:26:24

标签: elasticsearch

假设索引包含以下文档(自定义标记生成器以“。”字符分割)

        "doc_1": {
           "my_field": "aaa.bbb"
        },
        "doc_2": {
           "my_field": "ccc.ddd.eee"
        }

我需要提出一个问题,如果我将其作为输入"fff.ggg.ccc.ddd.eee",则将doc_2作为匹配返回。

如果我将输入"hhh.bbb""aaa.ggg.bbb.hhh"作为输入,我就不会有任何结果。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

鉴于所提供的信息,这是我的解决方案:

  • 自定义分析器仅在搜索时将shingle给予查询的输入。为了不干扰您现有的映射,我为此创建了一个名为keyword的子字段,并在索引时使用keyword分析器(如果您需要任何大写/小写的细节,只需相应地更改此分析器)和我的shingle分析仪在搜索时间:
DELETE test
PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer",
          "filter": [
            "shingle"
          ]
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "pattern",
          "pattern": "\\."
        }
      },
      "filter": {
        "shingle": {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 3,
          "output_unigrams": false,
          "token_separator":"."
        }
      }
    }
  },
  "mappings": {
    "test": {
      "properties": {
        "my_field": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "text",
              "analyzer": "keyword", 
              "search_analyzer": "my_analyzer"
            }
          }
        }
      }
    }
  }
}
  • 测试数据:
POST /test/test/1
{
  "my_field": "aaa.bbb"
}
POST /test/test/2
{
  "my_field": "ccc.ddd.eee"
}
  • 在查询时,我使用了一个简单的match(将考虑我在映射中定义的搜索时间分析器),并将匹配来自keyword子的.keyword ed值字段:
GET /test/_search
{
  "query": {
    "match": {
      "my_field.keyword": "fff.ggg.ccc.ddd.eee"
    }
  }
}
GET /test/_search
{
  "query": {
    "match": {
      "my_field.keyword": "aaa.ggg.bbb.hhh"
    }
  }
}
GET /test/_search
{
  "query": {
    "match": {
      "my_field.keyword": "hhh.bbb"
    }
  }
}
GET /test/_search
{
  "query": {
    "match": {
      "my_field.keyword": "ccc.ddd"
    }
  }
}