在测试代码的时候偶然发现term并没有说的那么容易使用,特此记录
问题:常用的 term 查询, 可以用它处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)。term查询数字的时候并没有什么问题,但是当我们对字符串类型的字段进行term查询时可能会得到意想不到的情况,可能明明有记录却查询不到,也可能查询出不符合预期的记录。
我们创建一个普通的索引
PUT /test4
{
"mappings": {
"properties": {
"name":{
"type": "text"
}
}
}
}
往里面添加两条数据
POST /test4/_doc
{
"name":"我是大哥"
}
POST /test4/_doc
{
"name":"我是小哥"
}
使用精确查询值为哥的时候
GET /test4/_search
{
"query": {
"term": {
"name": "哥"
}
}
}
查出了值为哥的数据,接下来继续查询我是小哥
GET /test4/_search
{
"query": {
"term": {
"name": "我是小哥"
}
}
}
无值
原因:
使用analyze可以查看
GET /test4/_analyze
{
"field":"name",
"text": "我是小哥"
}
被拆分成一个一个的汉字了
原因:明确字段是否需要分词,不需要分词的字段就将type设置为keyword,可以节省空间和提高写性能。
ElasticSearch 5.0以后,String字段被拆分成两种新的数据类型: text用于全文搜索,会分词,而keyword用于关键词搜索,不进行分词。
对于字符串类型的字段,ES默认会再生成一个keyword字段用于精确索引。
解决办法:
1.新建索引时将字段的值设置成keyword
测试:
PUT /test5
{
"mappings": {
"properties": {
"name":{
"type":"keyword"
}
}
}
}
还是添加相同的值:
精确查询值为哥:
GET /test5/_search
{
"query": {
"term": {
"name": "哥"
}
}
}
查询值为我是小哥:
GET /test5/_search
{
"query": {
"term": {
"name": "我是小哥"
}
}
}
第一种方式生效
2.设置analyzer的值
设置为whitespace
PUT /test6
{
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "whitespace"
}
}
}
}
添加的值还是相同:
精确查询值:我是小哥
GET /test6/_search
{
"query": {
"term": {
"name": "我是小哥"
}
}
}
查询值:哥
精确查询解决
下面说一下analyzer的值
Standard:也就是我们的默认值,它会分词,并且按小写处理,这个就不演示了
simple:按照非字母切分,并且小写处理且按照空格拆分
GET _analyze
{
"analyzer": "simple",
"text": "Hello world"
}
stop:小写处理,并且过滤掉某些词(the ,is ,a)
GET _analyze
{
"analyzer": "stop",
"text": "the a is apple"
}
whitespace:按空格拆分
GET _analyze
{
"analyzer": "whitespace",
"text": "我是 你"
}
Language:支持语言:arabic, armenian, basque, bengali, bulgarian, catalan, czech, dutch, english, finnish, french, galician, german, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian, portuguese, romanian, russian, sorani, spanish, swedish, turkish。
GET _analyze
{
"analyzer": "english",
"text": "Love is Like a Tide"
}
根据空格来拆分,但如果是中文的话
GET _analyze
{
"analyzer": "chinese",
"text": "爱如潮水"
}
一个字一个字的拆分