如何模拟SQL LIKE'%term%'在Elasticsearch中查询?

时间:2017-03-16 12:06:39

标签: elasticsearch

我尝试在elasticsearch中实现搜索,该搜索应该在一个或多个字段中找到特定术语。术语可以由一个字母以及几个字母或几个单词组成。这个术语可以位于该领域的任何部分。它与SQL查询非常相似,其中的部分如下:

field1 like '%term%' or field2 like '%term%' or field3 like '%term%'

我可能有很多索引和许多类型,所以为了不为每个字段指定映射我决定使用动态模板。首先,我定义了分析部分

"analysis" : {
  "filter" : {
    "word_delimiter_filter" : {
      "type" : "word_delimiter"
    },
    "ngram_filter" : {
      "type" : "nGram",
      "min_gram" : "1",
      "max_gram" : "50"
    }
  },
  "analyzer" : {
    "custom_search_analyzer" : {
      "filter" : [ "lowercase", "word_delimiter_filter" ],
      "type" : "custom",
      "tokenizer" : "standard"
    },
    "ngram_analyzer" : {
      "filter" : [ "lowercase", "word_delimiter_filter", "ngram_filter" ],
      "type" : "custom",
      "tokenizer" : "standard"
    }
  }
}

它使我能够将一个可变长度的术语与该领域的任何部分相匹配:开头,中间或结尾以及整个单词。

我决定在 _all 字段中添加所有可搜索字段,并在此唯一字段中搜索字词。所以我的动态模板看起来像

{
  "mappings": {
    "my_type": {
      "_all" : {
        "analyzer" : "ngram_analyzer",
        "search_analyzer" : "custom_search_analyzer"
      },
      "dynamic_templates" : [{
        "searchable_fields": {
          "match_mapping_type" : "string",
          "match": "field1|field2|field3",
          "match_pattern": "regex",
          "mapping": {
            "type": "string",
            "fields": {
              "raw": {
                "type": "string",
                "index": "not_analyzed"
              }
            },
            "analyzer" : "ngram_analyzer",
            "search_analyzer" : "standard",
            "include_in_all": true
          }
        }
      }]
    }
  }
} 

当我在没有层次结构的情况下展平JSON时,它非常有用。当JSON与几个嵌套对象和对象数组相比复杂得多时,问题就出现了。在这些嵌套对象中,并非所有字段都是可搜索的,因此我需要指定要搜索的字段。我尝试了正则表达式匹配

"match": "nested_field1\\.field2|nested_field2.field1"

但这没有用。此外, path_match path_unmatch 只接受一条路径。所以我想知道如何实现与几个嵌套对象字段的匹配,以便将它们添加到 _all 字段中进行搜索。

P.S。我也想知道这是一种有效的方法来实现具有此类要求的搜索,并匹配 _all 字段,或者使用 multi_match 查询?

简单的json看起来像

  {
    "storeId": "15",
    "title": "London Store",
    "address": "15 Green Street London",
    "description": "Some description",
    "phone": "Some phone",
    "country": "UK",
    "dateCreated": 1382444820000
  }

更复杂的json

{
  "orderId": "1",
  "assistant": {
    "id": "12",
    "name": "John Doe"
  },
  "store": {
    "id": "15",
    "title": "London Store",
    "address": "15 Green Street London"
  },
  "items": [{
    "title": "Some Title",
    "description": "Some description",
    "attributes": {
      "size": "L",
      "colour": "black"
    }
  }],
  "payments": [{
    "paymentNumber": "SomeNumber",
    "status": "Finished"
  }]
}

0 个答案:

没有答案