ElasticSearch7.x + kibana7.x使用记录

目录

查询所有索引

查询索引的mapping信息

添加索引的同时添加mapping

在原有基础上新增字段

旧的索引迁移到新的索引(使用场景:数据迁移、索引优化、数据转换)

 查询索引下的文档总数

场景1:某一个字段的值是数组,如何存放?如何查询? 

场景2:对象内嵌套了数组,数组内又嵌套了对象,如何添加?如何查询?

场景3:向量的使用?


查询所有索引

GET _cat/indices

查询索引的mapping信息

# 把index_name改为你要查看的索引名
GET /index_name/_mapping

添加索引的同时添加mapping

# index_name为你要增加的索引名
# properties内的是你的字段 在这里创建了类型为integer的name字段
PUT /index_name
{
  "mappings" : {
    "properties" : {
      "name" : {
        "type" : "integer"
      }
    }
  }
}

在原有基础上新增字段

# 为index_name索引新增类型为text的title字段
# analyzer指定该字段的分词器,ik_max_word是IK分词器中细粒度分词的模式,与之相反的是ik_smart模式
# search_analyzer指定搜索时的分词器
PUT /index_name/_mapping
{
  "properties" : {
    "title" : {
      "type" : "text",
      "analyzer": "ik_max_word",
      "search_analyzer": "ik_max_word"
    }
  }
}

旧的索引迁移到新的索引(使用场景:数据迁移、索引优化、数据转换)

 es没法在原有的结构上修改,比如你原来的结构使用的是ik分词器中的ik_smart模式,后面你发现ik_max_word模式才是你需要的效果,你想在原来的结构上把ik_smart修改为ik_max_word是不行的,只能是新创建一个索引,把字段的分词器改成ik_max_word,然后再进行数据迁移即可。

# old_index_name是旧的索引名,new_index_name是新的索引名
# 从old_index_name数据迁移到new_index_name
POST _reindex
{
    "source":{
        "index": "old_index_name"
    },
    "dest":{
        "index": "new_index_name"
    }
}

数据迁移后旧索引下的数据还是存在的,不是说把所有数据迁移到新的索引后旧索引的数据就没了

 查询索引下的文档总数

当我们进行数据迁移,想要查看是否迁移完成的话可以使用这个查询文档数量是否对应上即可 

# 把index_name修改为你要查询的索引名
GET /_cat/count/index_name?v

场景1:某一个字段的值是数组,如何存放?如何查询? 

  • 新建一个测试索引名,添加可以存放数组的字段
# 跟创建普通的字段差不多,唯独多了fields,fields内指定了一个类型为keyword的name字段
# fields下的name对应的就是数组当中的一个个值
PUT /test_index_name
{
  "mappings" : {
    "properties" : {
      "my_array" : {
        "type" : "text",
        "analyzer" : "ik_max_word",
        "search_analyzer": "ik_max_word",
        "fields" : {
          "name" : {
            "type" : "keyword"
          }
        }
      }
    }
  }
}

响应:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "test_index_name"

  •  添加测试数据

假如我们有三个数组,分别是:

["张三", "李四"]

["橙留香", "菠萝吹雪", "陆小果"]

["疯清扬", "天山果姥", "无极"] 

单个添加: 

# 为test_index_name添加一条id为1的数据
PUT /test_index_name/_doc/1
{
  "my_array": ["张三", "李四"]
}

批量添加:

POST /test_index_name/_bulk
{"create":{"_id":"2"}}
{"my_array":["橙留香", "菠萝吹雪", "陆小果"]}
{"create":{"_id":"3"}}
{"my_array":["疯清扬", "天山果姥", "无极"]}

通过以上步骤已经添加了三条数据,接下来让我们查询看下效果 

  • 查询方式1
# 查询数组内name有张三的数据
GET /test_index_name/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {"my_array.name": "张三"}
        }
      ]
    }
  }
}

结果:

 可以看到查询出了包含张三的数据了

  • 查询方式2
GET /test_index_name/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {"my_array": "疯清扬"}
        }
      ]
    }
  }
}

 结果:

方式1是根据数组内的name值精确匹配,方式2是my_array字段的模糊匹配,因为我们一开始创建的my_array是text类型的,text类型会进行分词,因此可以用match进行模糊匹配,而my_array内的name是keyword类型的,keyword类型不会进行分词,它是一个整体,那么就可以用term进行精确匹配了,当然你也可以把keyword类型改成text类型,这样也可以进行模糊匹配了,可以自行探索下。

场景2:对象内嵌套了数组,数组内又嵌套了对象,如何添加?如何查询?

比如我们有两条数据是这样的:

第一条:

{

    "title": "果宝特攻",

    "data": {

        "role": "主角",

        "names": [

            {

                "name": "疯清扬"

            },

            {

                "name": "天山果姥"

            }

        ]

    }

}

第二条:

{

    "title": "倚天屠龙记",

    "data": {

        "role": "主角",

        "names": [

            {

                "name": "张无忌"

            },

            {

                "name": "张三丰"

            }

        ]

    }

}

看起来有点复杂哈,待会有你头大的,哈哈哈哈~

  • 建索引添加字段
PUT /test_index_name_1
{
  "mappings" : {
    "properties" : {
      "title" : {
        "type" : "keyword"
      },
      "data" : {
        "type" : "nested",
        "properties" : {
          "role" : {
            "type" : "keyword"
          },
          "names" : {
            "type" : "nested",
            "properties" : {
              "name" : {
                "type" : "keyword"
              }
            }
          }
        }
      }
    }
  }
}

让我们把索引结构抽出来和数据结构对比看下: 

可以看到除了使用到nested类型外,其他结构和普通的结构没什么区别,nested类型可以使用在对象或数组上,具体的介绍如下:

Nested数据类型的作用 

  • 独立查询:Nested数据类型是object数据类型的特殊版本,允许对象数组被索引,这样它们可以独立地被查询。

  • 内部结构:在内部,nested对象将数组中的每个对象作为一个单独的隐藏文档来索引,这意味着可以使用nested查询独立查询每个nested对象。

  • Lucene文档:每个nested对象都被索引为一个独立的Lucene文档。例如,如果我们索引了一个包含100个user对象的单一文档,那么会创建101个Lucene文档。比如我们有以下数据:

{
  "title": "Example Document",
  "users": [
    { "name": "Alice", "age": 30 },
    { "name": "Bob", "age": 25 }
  ]
}

这个示例的有两个user对象,对应两个 Lucene文档,而包含title字段和users字段是这两个 Lucene文档的父文档,因此这个示例会创建三个 Lucene文档(一个父文档、两个user对象)

  • 使用场景:只有在需要独立查询对象数组的特殊情况下,才应该使用nested类型。对于大量、随机的键值对,可以考虑使用flattened数据类型来代替,因为它能将整个对象映射为一个字段,并允许对其内容进行简单搜索。这是因为nested文档和查询通常都比较昂贵。

  • 性能警告:由于与nested映射相关的开销,Elasticsearch设置了一些设置来防止性能问题:

    • index.mapping.nested_fields.limit:一个索引中可以有的不同nested映射的最大数量。默认值为50。
    • index.mapping.nested_objects.limit:一个文档在所有nested类型中可以包含的嵌套JSON对象的最大数量。这个限制有助于防止文档包含太多的nested对象时出现内存溢出错误。默认值是10000。

 官方文档介绍:Nested field type | Elasticsearch Guide [7.17] | Elastic

通过上面的介绍你应该理解咱们创建的索引结构了,那么接下来让我们添加数据查询试试。

  • 添加数据
PUT /test_index_name_1/_doc/1
{
  "title": "果宝特攻",
  "data": {
    "role": "主角",
    "names": [
      {
        "name": "疯清扬"
      },
      {
        "name": "天山果姥"
      }
    ]
  }
}

PUT /test_index_name_1/_doc/2
{
  "title": "倚天屠龙记",
  "data": {
    "role": "主角",
    "names": [
      {
        "name": "张无忌"
      },
      {
        "name": "张三丰"
      }
    ]
  }
}
  • 查询
GET /test_index_name_1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "title": "果宝特攻"
          }
        },
        {
          "nested": {
            "path": "data",
            "query": {
              "bool": {
                "must": [
                  {
                    "nested": {
                      "path": "data.names",
                      "query": {
                        "bool": {
                          "must": [
                            {
                              "term": {
                                "data.names.name": "疯清扬"
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

结果:

 解释查询语句:

基本上就是一层嵌套一层的去查询,看下图的解释应该就明白了:

 

如果我想添加role字段的查询条件呢?其实就是在data对象层添加一个条件即可,对比:

场景3:向量的使用?

在es没有添加向量的搜索方式前,搜索靠的是关键字,但是关键字的搜索结果在有些时候不是那么尽人意,因此有了向量的方式后在一定程度上可以做到语义上的搜索,不过我们需要使用Embedding将文本转为向量,效果好不好就看你的Embedding模型好不好了。

流程:

我们需要借助Embedding模型将文本转为向量,然后入库。在查询的时候将查询的问题借助Embedding转为向量,然后拿着向量去库里查。流程大概是这么个流程。

  • 建索引添加字段
PUT /test_index_name_2
{
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_max_word"
      },
      "my_v": {
        "type": "dense_vector",
        "dims": 1024
      }
    }
  }
}

新建了两个字段,一个是content字段,指定了ik分词器。一个是my_v字段,类型是dense_vector,也就是向量类型,dims指的是向量的维度,因为接下来用的Embedding模型维度是1024的,因此这里的dims填1024即可,如果你用其他的Embedding模型,那么就需要看你的Embedding模型维度是多少了。一般Embedding模型的文档会说明维度是多少的。

  •  下载模型

这一步因为用到了Embedding模型,因此我们需要在代码中添加,这里就用python演示了,接下来的演示我将使用这个Embedding模型:

https://github.com/FlagOpen/FlagEmbedding

git lfs install
git clone https://huggingface.co/BAAI/bge-large-zh
  •  部署模型

安装依赖

pip install -U FlagEmbedding

 示例代码:

# -*- coding: utf-8 -*-
from FlagEmbedding import FlagModel

# 模型路径
MODEL_PATH = 'D:/python_project/pythonProject/bge-large-zh'

if __name__ == '__main__':
    model = FlagModel(MODEL_PATH)
    my_v = model.encode("这是一个测试转向量的文本")
    print(my_v)
    print(f'向量维度:{len(my_v)}')

输出结果:

  • es入库 

 我的elasticsearch数据库是7.12.1的

安装elasticsearch依赖:

pip install elasticsearch==7.17.0

示例代码:

# -*- coding: utf-8 -*-
from FlagEmbedding import FlagModel
from elasticsearch import Elasticsearch

# 模型路径
MODEL_PATH = 'D:/python_project/pythonProject/bge-large-zh'

if __name__ == '__main__':
    content = '橙留香来自一位三流剑客之家,与果冻武术学院里的菠萝吹雪、陆小果组成“果冻三剑客”,最后三人终于打败四大恶贼,成为民族大英雄。'
    # 加载模型
    model = FlagModel(MODEL_PATH)
    # 初始化es连接  如果没有账户密码不填即可
    es = Elasticsearch([{'host': '127.0.0.1', 'port': 9200}], http_auth=('elastic', '123456789'))
    # 文本转向量
    my_v = model.encode(content)
    print(my_v)
    print(f'向量维度:{len(my_v)}')
    # 入库
    data = {
        "my_v": my_v,
        "content": content
    }
    response = es.index(index="test_index_name_2", document=data)
    print(response)

  • 查询

示例代码:

# -*- coding: utf-8 -*-
import json

from FlagEmbedding import FlagModel
from elasticsearch import Elasticsearch

# 模型路径
MODEL_PATH = 'D:/python_project/pythonProject/bge-large-zh'

if __name__ == '__main__':
    question = '果冻三剑客是谁?'
    # 加载模型
    model = FlagModel(MODEL_PATH)
    # 初始化es连接  如果没有账户密码不填即可
    es = Elasticsearch([{'host': '127.0.0.1', 'port': 9200}], http_auth=('elastic', '123456789'))
    # 文本转向量
    my_v = model.encode(question)
    # 查询条件
    dsl = {
        "script_score": {
            "query": {
                "match_all": {}
            },
            "script": {
                "source": """
                    if (doc.containsKey('my_v') && doc['my_v'].size() > 0 && params.query_vector != null) {
                        return cosineSimilarity(params.query_vector, 'my_v') + 1.0
                    }else {
                        return 0
                    }
                """,
                "params": {"query_vector": my_v}
            }
        }
    }
    # 查询
    result = es.search(index="test_index_name_2", query=dsl)
    print(json.dumps(result, indent=2, ensure_ascii=False))

 结果:

你可能会看到很多-0.007382424082607031这种数据,这个就是文本的向量

代码解释:

 


👍点赞,你的认可是我创作的动力 !
🌟收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/84778.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

回归预测 | MATLAB实现WOA-SVM鲸鱼算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现WOA-SVM鲸鱼算法优化支持向量机多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现WOA-SVM鲸鱼算法优化支持向量机多输入单输出回归预测(多指标,多图)效果一览基本介绍程…

【操作系统】寄存器

概念 寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器…

作为一名8年测试工程师,因为偷偷接私活被····

接私活 对程序员这个圈子来说是一个既公开又隐私的话题,不说全部,应该大多数程序员都有过想要接私活的想法,当然,也有部分得道成仙的不主张接私活。但是很少有人在公开场合讨论私活的问题,似乎都在避嫌。就跟有人下班后…

2023河南萌新联赛第(五)场:郑州轻工业大学

A.买爱心气球 原题链接 : 登录—专业IT笔试面试备考平台_牛客网 博弈论 : #include <iostream> using namespace std; int t,n,m; string s1 "Alice",s2 "Bob"; int main() {cin>>t;while(t--){cin>>n>>m;if (n % 3 0) {cou…

简单介绍 CPU 的工作原理

内部架构 CPU 的根本任务就是执行指令&#xff0c;对计算机来说最终都是一串由 0 和 1 组成的序列。CPU 从逻辑上可以划分成 3 个模块&#xff0c;分别是控制单元、运算单元和存储单元 。其内部架构如下&#xff1a; 【1】控制单元 控制单元是整个CPU的指挥控制中心&#xff…

[ubuntu]ubuntu安装vncserver后,windows连接灰屏解决方法

修改配置文件~/.vnc/xstartup为如下内容&#xff1a; #!/bin/bash export $(dbus-launch) export XKL_XMODMAP_DISABLE1 unset SESSION_MANAGERgnome-panel & gnome-settings-daemon & metacity & nautilus & gnome-terminal &# [ -x /etc/vnc/xstartup…

将ChatGPT集成整合到业务中时,3个要做和3个不要做的事项

​关于ChatGPT的讨论甚多&#xff0c;毫无疑问的是&#xff0c;几乎每个人都应该使用它&#xff0c;无论用于个人生活问题的解答还是工作中简化日常任务。越来越多的行业也正在探索这项技术的应用场景&#xff0c;从优化客户服务体验、简化旅行计划到便捷的内容创作等&#xff…

负载均衡下的webshell

文章目录 1.场景描述2.在蚁剑里添加 Shell3.因为负载均衡而出现的问题4.问题解决方案4.1 方案14.2 方案24.3 方案3 1.场景描述 当前手里有一个以docker部署的Tomcat负载均衡环境。主机对外ip和端口为192.168.100.130:18080 我们假设其为一个真实的业务系统&#xff0c;存在一…

亚马逊云科技 云技能孵化营——机器学习心得

亚马逊云科技 云技能孵化营机器学习心得 前言什么是机器学习&#xff1f;机器学习如何解决业务问题&#xff1f;什么时候适合使用机器学习模型&#xff1f;总结 前言 很荣幸参加了本次亚马逊云科技云技能孵化营&#xff0c;再本期的《亚马逊云科技云技能孵化营》中&#xff0c…

idea2023 springboot2.7.5+mybatis+jsp 初学单表增删改查

创建项目 因为2.7.14使用量较少&#xff0c;特更改spring-boot为2.7.5版本 配置端口号 打开Sm01Application类&#xff0c;右键运行启动项目&#xff0c;或者按照如下箭头启动 启动后&#xff0c;控制台提示如下信息表示成功 此刻在浏览器中输入&#xff1a;http://lo…

scala中json4s 使用详解

预备知识 json4s的数据结构AST (Abstract Syntax Tree)。 sealed abstract class JValue case object JNothing extends JValue // zero for JValue case object JNull extends JValue case class JString(s: String) extends JValue case class JDouble(num: Double) extend…

C++实现字符串的逆置

目录 C和C的区别 【1】C对C的扩充 【2】C对C的兼容 第一个C程序 【1】hello world 【2】cout标准输出流对象 i&#xff09;介绍 ii&#xff09;运算 iii&#xff09;cout的使用 iv&#xff09;使用cout指定格式的输出 练习&#xff1a;1、输出斐波那契的前10项。 【3】…

【Java从0到1学习】10 Java常用类汇总

1. System类 System类对读者来说并不陌生&#xff0c;因为在之前所学知识中&#xff0c;需要打印结果时&#xff0c;使用的都是“System.out.println();”语句&#xff0c;这句代码中就使用了System类。System类定义了一些与系统相关的属性和方法&#xff0c;它所提供的属性和…

使用 Feature Flags 与可观测工具实现数据库灰度迁移

场景描述 很多企业会遇到数据库升级、或数据库迁移的情况&#xff0c;尤其是在自建数据库服务向云数据库服务、自建机房向云机房、旧数据库向新数据库迁移等场景。 然而&#xff0c;我们需要在整个移植过程中保证其稳定性、避免数据遗失、服务宕机等情况&#xff0c;最常见的移…

将eNSP Pro部署在华为云是什么体验

eNSP Pro简介 eNSP Pro 是华为公司数据通信产品线新推出的数通设备模拟器&#xff0c;主要应用在数据通信技能培训&#xff0c;为使用者提供华为数据通信产品设备命令行学习环境。 具备的能力 多产品模拟能力&#xff1a;支持数据通信产品线NE路由器、CE交换机、S交换机、AR…

实验二 Hdoop2.7.6+JDK1.8+SSH的安装部署与基本操作

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

阿里云CDN加速器基本概念与购买开通

文章目录 1.CDN加速器的基本概念1.1.CDN加速器基本介绍1.2.网站引入CDN加速器的架构图1.3.CDN加速器的工作原理1.4.引入CDN后域名解析变成了CNAME&#xff1f; 2.开通阿里云CDN加速服务 1.CDN加速器的基本概念 CDN加速器官方文档&#xff1a;https://help.aliyun.com/product/…

Spring Clould 部署 - Docker

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; 初识Docker-什么是Docker&#xff08;P42&#xff0c;P43&#xff09; 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&…

Redis Lua脚本执行原理和语法示例

Redis Lua脚本语法示例 文章目录 Redis Lua脚本语法示例0. 前言参考资料 1. Redis 执行Lua脚本原理1.1. 对Redis源码中嵌入Lua解释器的简要解析&#xff1a;1.2. Redis Lua 脚本缓存机制 2. Redis Lua脚本示例1.1. 场景示例1. 请求限流2. 原子性地从一个list移动元素到另一个li…

计算机网络第2章(物理层)

计算机网络第2章&#xff08;物理层&#xff09; 2.1 物理层的基本概念2.2 物理层下面的传输媒体2.2.1 导引型传输媒体2.2.2 非导引型传输媒体 2.3 传输方式2.3.1 串行传输和并行传输2.3.2 同步传输和异步传输2.3.3 单向通信&#xff08;单工&#xff09;、双向交替通信&#x…