Elasticsearch中基于wildcardQuery的中文模糊查询

阅读数:315 评论数:0

跳转到新版页面

分类

应用软件

正文

SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.wildcardQuery("awardName.keyword", "*" + personAward.getAwardName() + "*"))
            .build();
List<PersonAward> holidaysList = elasticsearchTemplate.queryForList(searchQuery, PersonAward.class);

注意,字段后面加了一个keyword,如果不加,中文搜索可能只针对单个字有效。

忽略大小写

在kibaba的Dev Tools Console中执行

put mbstudy_poetry_authors
{
  "mappings": {
    "properties": {
      "poetryAuthor": {
        "type": "keyword",
        "normalizer": "lowercase"
      }
    }
  },
  "settings": {
    "analysis": {
      "normalizer": {
        "lowercase": {
          "type": "custom",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  }
}

normalizer是keyword的一个属性,可以对keyword生成单一Term再做进一步的处理,比如lowercase,即做小写变换,使用方法 和自定义分析器有些类似。

文档写入时由于加入了normalizer,所有term都会被做小写处理,查询搜索同样采用normalizer配置,因些处理后的term也是小写的。

索引和搜索分词

1、文本分词会发生在两个地方:

(1)创建索引:当索引文档字符类型为text时,在建立索引时会对该字段时行分词。

(2)搜索:会对用户输入的文本进行分词。

ES分词流程

Character filter(0或多个) --> Tokenizer(只能有一个) --> Token filters(0或多个)

 从文档中提出若干Token,这些算法称为Tokenizer(分词器),这些Token会被进一步处理,比如转成小写等,这些处理算法被称为Token Filter,被处理后的结果被称为Term(词),文档中包含几个这样的Term被称为Frequency(词频)。引擎会建立Term和原文档的Inverted Index(倒排索引),这样就能根据Term很快找到源文档了。文本被Tokenizer处理前可能要做一些预处理,比如去掉里面的HTML标记,这些处理的算法被称为Character Filter(字符过滤器), 这整个的分析算法被称为Analyzer(分析器)

分词器测试 

默认ES使用standard analyzer,可以通过_analyzer API来测试分词的效果

POST _analyze
{
  "analyzer": "standard",
  "text": "The quick brown fox"
}
响应
{
  "tokens" : [
    {
      "token" : "the",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "quick",
      "start_offset" : 4,
      "end_offset" : 9,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "brown",
      "start_offset" : 10,
      "end_offset" : 15,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "fox",
      "start_offset" : 16,
      "end_offset" : 19,
      "type" : "<ALPHANUM>",
      "position" : 3
    }
  ]
}
指定token filter
POST _analyze
{
  "tokenizer": "standard",
  "filter": ["lowercase"],
  "text": "The quick brown fox"
}
{
  "tokens" : [
    {
      "token" : "the",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "quick",
      "start_offset" : 4,
      "end_offset" : 9,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "brown",
      "start_offset" : 10,
      "end_offset" : 15,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "fox",
      "start_offset" : 16,
      "end_offset" : 19,
      "type" : "<ALPHANUM>",
      "position" : 3
    }
  ]
}

1、创建索引前设置一个自定义的analyzer

 

PUT /my_index?pretty
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_folded": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type": "text",
        "analyzer": "std_folded" 
      }
    }
  }
}


GET /my_index/_analyze?pretty
{
  "analyzer": "std_folded", 
  "text":     "Is this déjà vu?"
}


GET /my_index/_analyze?pretty
{
  "field": "my_text", 
  "text":  "Is this déjà vu?"
}
面操作我们自定义了一个分析器std_folded,它的tokenizerstandard,同时有两个token filter分别为:lowercaseasiciifolding。我们在定义mapping时,设置了一个字段名为my_text,它的类型为text,我们指定它使用的分析器为我们定义的std_folded。
 
2、配置内置分析器

内置的分词器无需任何配置我们就可以使用。但是我们可以修改内置的部分选项修改它的行为。

DELETE my_index

PUT /my_index?pretty
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_english": { 
          "type":      "standard",
          "stopwords": "_english_"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type":     "text",
        "analyzer": "standard", 
        "fields": {
          "english": {
            "type":     "text",
            "analyzer": "std_english" 
          }
        }
      }
    }
  }
}


POST /my_index/_analyze?pretty
{
  "field": "my_text", 
  "text": "The old brown cow"
}


POST /my_index/_analyze?pretty
{
  "field": "my_text.english", 
  "text": "The old brown cow"
}
上面的例子中,我们配置分析器std_english,它使用的分析器为standard分析器,他的停词列表设置为_english_.然后字段my_text使用的是standard分析器,而字段my_text.english使用的是我们配置的std_english.

创建自定义分析器

当内置的分词器无法满足需求时,可以创建custom类型的分析器。

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer":{
          "type":"custom",
          "tokenizer":"standard",
          "char_filter":["html_strip"],
          "filter":["lowercase","asciifolding"]
        }
      }
    }
  }
}

 




相关推荐