text字段和keyword字段的区别
keyword
首先了解一下什么是keyword,举个例子:
建立一个索引test_index,将字段name设置为keyword类型。
PUT test_index
{
"mappings": {
"user": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
}
然后查询该mapping是否已经构建成功。
GET test_index/_mapping
得到如下结果:
{
"test_index": {
"mappings": {
"user": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
}
}
表示已经创建成功。
在该索引test_index下建立数据:
POST test_index/user
{
"name":"奥尼尔"
}
使用term查询数据,name为“奥尼尔”:
GET test_index/user/_search
{
"query": {
"term": {
"name": {
"value": "奥尼尔"
}
}
}
}
得到结果:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "test_index",
"_type": "user",
"_id": "71pbn2kBcbRJikqN_vnl",
"_score": 0.2876821,
"_source": {
"name": "奥尼尔"
}
}
]
}
}
接下来使用term查询数据,name为“奥尼”:
GET test_index/user/_search
{
"query": {
"term": {
"name": {
"value": "奥尼"
}
}
}
}
得到结果:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
因为字段被设置成keyword类型,录入数据该字段是不会被分词,所以使用term查询时候,需要全匹配才能查询到。
text
更新test_index的mapping:
PUT test_index/_mapping/user?update_all_types
{
"properties": {
"school": {
"type": "text"
}
}
}
查看mapping:
{
"test_index": {
"mappings": {
"user": {
"properties": {
"name": {
"type": "keyword"
},
"school": {
"type": "text"
}
}
}
}
}
}
添加数据:
POST test_index/user
{
"name":"奥尼尔",
"school":"hello world"
}
然后我们查询school字段:
GET test_index/user/_search
{
"query": {
"term": {
"school": {
"value": "world"
}
}
}
}
结果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "test_index",
"_type": "user",
"_id": "8lptn2kBcbRJikqNqvk0",
"_score": 0.2876821,
"_source": {
"name": "奥尼尔",
"school": "hello world"
}
}
]
}
}
可以发现,即使没有输入完整的查询条件,也能将school为"hello world"的内容查询到。
如果我们完整查询:
GET test_index/user/_search
{
"query": {
"term": {
"school": {
"value": "hello world"
}
}
}
}
结果:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
完整输入结果查找不到。
因为text,会将字段进行分词,如“hello world”会被分词为["hello","world",...],而term必须匹配到数组中的一项,才能查出结果。
match,match_phrase和term区别
elastic会对查询语句进行分词
term
term 查询语句不分词
term查询keyword字段
keyword字段不分词
term查询keyword字段,需要完全匹配
term查询text字段
text字段分词
term查询text字段,必须为text字段分词后中的某一个才行。如“我真帅”分词为["我","真","帅"],term必须为“我”或“真”或“帅”,才能查到,而“我帅”、“真帅”不行。
match
match 查询语句分词
match查询keyword字段
keyword字段不分词
match查询keyword字段,需要完全匹配
match查询text字段
text字段分词
match查询text字段,只需要match分词结果中和text分词有匹配就可以查出。如“我真帅”分词为["我","真","帅"],match的查询语句“真帅”被分词为["真","帅"],其中“真”、“帅”能匹配上text字段的分词结果,所以能查出。
match_phrase
match_phrase 查询语句分词
match_phrase 查询keyword字段
keyword字段不分词
match_phrase 查询keyword字段,需要完全匹配
match_phrase 查询text字段
text字段分词
match_phrase 查询text字段,只需要match_phrase 分词结果中和text分词有匹配且查询语句必须包含在text分词结果中,同时顺序相同且连续,才可以查出。如“我真帅”分词为["我","真","帅",“真帅”],match_phrase 的查询语句“真帅”被分词为["真帅"],其中“真帅”能匹配上text字段的分词结果,连续且顺序相同,所以能查出。