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
,它的tokenizer
为standard
,同时有两个token filter
分别为:lowercase
和asiciifolding
。我们在定义mapping时,设置了一个字段名为my_text
,它的类型为text
,我们指定它使用的分析器为我们定义的std_folded。
内置的分词器无需任何配置我们就可以使用。但是我们可以修改内置的部分选项修改它的行为。
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"]
}
}
}
}
}