1、关于对象类型的操作和查询
创建索引,插入数据
代码语言:javascript复制PUT /blog
{
"mappings": {
"properties": {
"Content":{
"type": "text"
},
"CreateTime":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"Author":{
"properties": {
"UserName":{
"type":"keyword"
},
"Adress": {
"type": "text"
}
}
}
}
}
}
PUT blog/_doc/1
{
"Content":"i learn Elasticsearch",
"time":"2020-01-01 00:00:00",
"Author":{
"UserName":"mark",
"Adress":"hangzhou"
}
}
现在需要统计作为为mark,文章内容为Elasticsearch的文档记录,代码如下:
代码语言:javascript复制GET blog/_search
{
"query": {
"bool": {
"must": [
{"match": {
"Content": "Elasticsearch"
}},{
"match": {
"Author.UserName": "mark"
}
}
]
}
}
}
搜索结果如下:
代码语言:javascript复制{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "blog",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"Content" : "i learn Elasticsearch",
"time" : "2020-01-01 00:00:00",
"Author" : {
"UserName" : "mark",
"Adress" : "hangzhou"
}
}
}
]
}
}
当嵌套对象只有一个时,搜索是正常的,但是注意下面关于2的用法
2、关于对象数组的操作
代码语言:javascript复制PUT /blog
{
"mappings": {
"properties": {
"Content":{
"type": "text"
},
"CreateTime":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"Author":{
"properties": {
"UserName":{
"type":"keyword"
},
"Adress": {
"type": "text"
}
}
}
}
}
}
PUT blog/_doc/1
{
"Content":"i learn Elasticsearch",
"time":"2020-01-01 00:00:00",
"Author":[
{
"UserName":"mark",
"Adress":"hangzhou"
},
{
"UserName":"jerry",
"Adress":"shanghai"
}
]
}
当博客存在两个作者时,此时需要搜索作者名为mark,且联系地址时shanghai的记录,显然是不存在的,代码如下:
代码语言:javascript复制GET blog/_search
{
"query": {
"bool": {
"must": [
{"match": {
"Author.Adress": "shanghai"
}},{
"match": {
"Author.UserName": "mark"
}
}
]
}
}
}
搜索结果如下:
代码语言:javascript复制{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.64933956,
"hits" : [
{
"_index" : "blog",
"_id" : "1",
"_score" : 0.64933956,
"_source" : {
"Content" : "i learn Elasticsearch",
"time" : "2020-01-01 00:00:00",
"Author" : [
{
"UserName" : "mark",
"Adress" : "hangzhou"
},
{
"UserName" : "jerry",
"Adress" : "shanghai"
}
]
}
}
]
}
}
此时,存在结果,显示是不对的.这里看官方的介绍,当将字段描述成object类型时,存入的数组对象,es会移除对象数组中对象属性之间的关联关系,也就是说如下代码:
代码语言:javascript复制{
"UserName" : "mark",
"Adress" : "hangzhou"
}
es会移除UserName和Adress的关联关系,彼此是独立的,从而建立如下关系
代码语言:javascript复制{
"Author.Adress" : [ "hangzhou", "shanghai" ],
"Author.UserName" : [ "mark", "jerry" ]
}
所以失去了关联关系之后的搜索,只能按照keyvalue的形式进行搜索,从而返回值,所以这里must查询可以查询到结果,所以解决这个问题,只能通过将字段描述成Nested类型
3、Nested类型
3.1 解决object的问题
代码语言:javascript复制PUT /blog
{
"mappings": {
"properties": {
"Content":{
"type": "text"
},
"CreateTime":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"Author":{
"type": "nested",
"properties": {
"UserName":{
"type":"keyword"
},
"Adress": {
"type": "text"
}
}
}
}
}
}
PUT blog/_doc/1
{
"Content":"i learn Elasticsearch",
"time":"2020-01-01 00:00:00",
"Author":[
{
"UserName":"mark",
"Adress":"hangzhou"
},
{
"UserName":"jerry",
"Adress":"shanghai"
}
]
}
因为2中存在的问题,此时将Author描述成Nested类型,在执行如下搜索
代码语言:javascript复制GET blog/_search
{
"query": {
"bool": {
"must": [
{"match": {
"Author.Adress": "shanghai"
}},{
"match": {
"Author.UserName": "mark"
}
}
]
}
}
}
结果如下:
代码语言:javascript复制{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
此时结果正确,Nested类型的文档会被保存在两个Lucene文档中,查询时做 join 处理
3.2 通过nested实现类似关系型数据库的join关联条件限制查询
查询文章内容中包含Elasticsearch且作者为mark的记录
代码语言:javascript复制GET blog/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"Content": "Elasticsearch"
}
},
{
"nested": {
"path": "Author",
"query": {
"bool": {
"must": [
{
"match": {
"Author.UserName": "mark"
}
}
]
}
}
}
}
]
}
}
}
结果如下:
代码语言:javascript复制{
"took" : 222,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.3862944,
"hits" : [
{
"_index" : "blog",
"_id" : "2",
"_score" : 1.3862944,
"_source" : {
"Content" : "i learn Elasticsearch",
"time" : "2020-01-01 00:00:00",
"Author" : [
{
"UserName" : "scott",
"Adress" : "newyork"
},
{
"UserName" : "sam",
"Adress" : "english"
}
]
}
}
]
}
}