前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES 复杂类型及其查询

ES 复杂类型及其查询

作者头像
郑小超.
发布2022-09-23 18:48:53
5110
发布2022-09-23 18:48:53
举报
文章被收录于专栏:GreenLeaves

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"
            }
          ]
        }
      }
    ]
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档