Elasticsearch:Retrievers 介绍 - Python Jupyter notebook
在今天的文章里,我是继上一篇文章 “Elasticsearch:介绍 retrievers - 搜索一切事物” 来使用一个可以在本地设置的 Elasticsearch 集群来展示 Retrievers 的使用。在本篇文章中,你将学到如下的内容:
- 从 Kaggle 下载 IMDB 数据集
- 创建两个推理服务
- 部署 ELSER
- 部署 e5-small
- 创建摄取管道
- 创建映射
- 摄取 IMDB 数据,在摄取过程中创建嵌入
- 缩小查询负载模型
- 运行示例检索器
安装
Elasticsearch 及 Kibana
如果你还没有安装好自己的 Elasticsearch 及 Kibana,请参考如下的链接来进行安装:
- 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
- Kibana:如何在 Linux,MacOS 及 Windows上安装 Elastic 栈中的 Kibana
在安装的时候,我们选择 Elastic Stack 8.x 来进行安装。在首次启动 Elasticsearch 的时候,我们可以看到如下的输出:
在上面,我们可以看到 elastic 超级用户的密码。我们记下它,并将在下面的代码中进行使用。
我们还可以在安装 Elasticsearch 目录中找到 Elasticsearch 的访问证书:
$ pwd
/Users/liuxg/elastic/elasticsearch-8.14.1/config/certs
$ ls
http.p12 http_ca.crt transport.p12
在上面,http_ca.crt 是我们需要用来访问 Elasticsearch 的证书。
我们首先克隆已经写好的代码:
git clone https://github.com/liu-xiao-guo/elasticsearch-labs
我们然后进入到该项目的根目录下:
$ pwd
/Users/liuxg/python/elasticsearch-labs/supporting-blog-content/introducing-retrievers
$ ls
retrievers_intro_notebook.ipynb
如上所示,retrievers_intro_notebook.ipynb 就是我们今天想要工作的 notebook。
我们通过如下的命令来拷贝所需要的证书:
$ pwd
/Users/liuxg/python/elasticsearch-labs/supporting-blog-content/introducing-retrievers
$ cp ~/elastic/elasticsearch-8.14.1/config/certs/http_ca.crt .
$ ls
http_ca.crt retrievers_intro_notebook.ipynb
安装所需要的 python 依赖包
pip3 install -qqq pandas elasticsearch python-dotenv
我们可以使用如下的方法来查看 elasticsearch 的版本:
$ pip3 list | grep elasticsearch
elasticsearch 8.14.0
创建环境变量
为了能够使得下面的应用顺利执行,在项目当前的目录下运行如下的命令:
export ES_ENDPOINT="localhost"
export ES_USER="elastic"
export ES_PASSWORD="uK+7WbkeXMzwk9YvP-H3"
你需要根据自己的 Elasticsearch 设置进行相应的修改。
下载数据集
我们去到地址 IMDB movies dataset | Kaggle 下载数据集并解压缩。
$ pwd
/Users/liuxg/python/elasticsearch-labs/supporting-blog-content/introducing-retrievers
$ ls
archive (13).zip http_ca.crt retrievers_intro_notebook.ipynb
$ unzip archive\ \(13\).zip
Archive: archive (13).zipinflating: imdb_movies.csv
$ mkdir -p content
$ mv imdb_movies.csv content/
$ tree -L 2
.
├── archive\ (13).zip
├── content
│ └── imdb_movies.csv
├── http_ca.crt
└── retrievers_intro_notebook.ipynb
如上所示,我们吧 imdb_movies.csv 文件置于当前工作目录下的 content 目录下。
代码展示
我们在当前项目的根目录下打入如下的命令:
设置
import os
import zipfile
import pandas as pd
from elasticsearch import Elasticsearch, helpers
from elasticsearch.exceptions import ConnectionTimeout
from elastic_transport import ConnectionError
from time import sleep
import time
import logging# Get the logger for 'elastic_transport.node_pool'
logger = logging.getLogger("elastic_transport.node_pool")# Set its level to ERROR
logger.setLevel(logging.ERROR)# Suppress warnings from the elastic_transport module
logging.getLogger("elastic_transport").setLevel(logging.ERROR)
连接到 Elasticsearch
from dotenv import load_dotenvload_dotenv()ES_USER = os.getenv("ES_USER")
ES_PASSWORD = os.getenv("ES_PASSWORD")
ES_ENDPOINT = os.getenv("ES_ENDPOINT")
COHERE_API_KEY = os.getenv("COHERE_API_KEY")url = f"https://{ES_USER}:{ES_PASSWORD}@{ES_ENDPOINT}:9200"
print(url)es = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)
print(es.info())
如上所示,我们的客户端连接到 Elasticsearch 是成功的。
部署 ELSER 及 E5
下面的两个代码块将部署嵌入模型并自动扩展 ML 容量。
部署及启动 ELSER
from elasticsearch.exceptions import BadRequestErrortry:resp = es.options(request_timeout=5).inference.put_model(task_type="sparse_embedding",inference_id="my-elser-model",body={"service": "elser","service_settings": {"num_allocations": 64, "num_threads": 1},},)
except ConnectionTimeout:pass
except BadRequestError as e:print(e)
如果你之前已经部署过 ELSER,你可能会得到一个 resource already exists 这样的错误。你可以使用如下的命令来删除之前的 inference_id。
DELETE /_inference/my-elser-model
在运行完上面的命令后,需要经过一定的时间下载 ELSER 模型。这个依赖于你的网络速度。我们可以在 Kibana 中进行查看:
部署及启动 es-small
try:resp = es.inference.put_model(task_type="text_embedding",inference_id="my-e5-model",body={"service": "elasticsearch","service_settings": {"num_allocations": 8,"num_threads": 1,"model_id": ".multilingual-e5-small",},},)
except ConnectionTimeout:pass
except BadRequestError as e:print(e)
在运行完上面的代码后,我们可以在 Kibana 界面中:
点击上面的 "Add trained model" 来安装 .multilingual-e5-small 模型。
我们到最后能看到这个:
整个下载及部署需要很长的时间,需要你耐心等待!
提示:如果你的机器是在 x86 架构的机器上运行的话,那么你在上面可以选择 .multilingual-e5-small_linux-x86_64 作为其 model_id。
检查模型部署状态
这将循环检查,直到 ELSER 和 e5 都已完全部署。如果你在上面已经等了足够久的话,那么下面的代码讲很快地执行。
如果需要分配额外容量来运行模型,这可能需要几分钟
from time import sleep
from elasticsearch.exceptions import ConnectionTimeoutdef wait_for_models_to_start(es, models):model_status_map = {model: False for model in models}while not all(model_status_map.values()):try:model_status = es.ml.get_trained_models_stats()except ConnectionTimeout:print("A connection timeout error occurred.")continuefor x in model_status["trained_model_stats"]:model_id = x["model_id"]# Skip this model if it's not in our list or it has already startedif model_id not in models or model_status_map[model_id]:continueif "deployment_stats" in x:if ("nodes" in x["deployment_stats"]and len(x["deployment_stats"]["nodes"]) > 0):if (x["deployment_stats"]["nodes"][0]["routing_state"]["routing_state"]== "started"):print(f"{model_id} model deployed and started")model_status_map[model_id] = Trueif not all(model_status_map.values()):sleep(0.5)models = [".elser_model_2", ".multilingual-e5-small"]
wait_for_models_to_start(es, models)
.elser_model_2 model deployed and started
.multilingual-e5-small model deployed and started
创建索引模板并链接到摄取管道
template_body = {"index_patterns": ["imdb_movies*"],"template": {"settings": {"index": {"default_pipeline": "elser_e5_embed"}},"mappings": {"properties": {"budget_x": {"type": "double"},"country": {"type": "keyword"},"crew": {"type": "text"},"date_x": {"type": "date", "format": "MM/dd/yyyy||MM/dd/yyyy[ ]"},"genre": {"type": "keyword"},"names": {"type": "text"},"names_sparse": {"type": "sparse_vector"},"names_dense": {"type": "dense_vector"},"orig_lang": {"type": "keyword"},"orig_title": {"type": "text"},"overview": {"type": "text"},"overview_sparse": {"type": "sparse_vector"},"overview_dense": {"type": "dense_vector"},"revenue": {"type": "double"},"score": {"type": "double"},"status": {"type": "keyword"},}},},
}# Create the template
es.indices.put_index_template(name="imdb_movies", body=template_body)
创建采集管道
# Define the pipeline configuration
pipeline_body = {"processors": [{"inference": {"model_id": ".multilingual-e5-small","description": "embed names with e5 to names_dense nested field","input_output": [{"input_field": "names", "output_field": "names_dense"}],}},{"inference": {"model_id": ".multilingual-e5-small","description": "embed overview with e5 to names_dense nested field","input_output": [{"input_field": "overview", "output_field": "overview_dense"}],}},{"inference": {"model_id": ".elser_model_2","description": "embed overview with .elser_model_2 to overview_sparse nested field","input_output": [{"input_field": "overview", "output_field": "overview_sparse"}],}},{"inference": {"model_id": ".elser_model_2","description": "embed names with .elser_model_2 to names_sparse nested field","input_output": [{"input_field": "names", "output_field": "names_sparse"}],}},],"on_failure": [{"append": {"field": "_source._ingest.inference_errors","value": [{"message": "{{ _ingest.on_failure_message }}","pipeline": "{{_ingest.pipeline}}","timestamp": "{{{ _ingest.timestamp }}}",}],}}],
}# Create the pipeline
es.ingest.put_pipeline(id="elser_e5_embed", body=pipeline_body)
提取文档
这将
- 进行一些预处理
- 批量提取 10,178 条 IMDB 记录
- 使用 ELSER 模型为 overview 和 name 字段生成稀疏向量嵌入
- 使用 ELSER 模型为 overview 和 name 字段生成密集向量嵌入
使用上述分配设置通常需要一定的时间才能完成。这个依赖于你自己电脑的配置。
# Load CSV data into a pandas DataFrame
df = pd.read_csv("./content/imdb_movies.csv")# Replace all NaN values in DataFrame with None
df = df.where(pd.notnull(df), None)# Convert DataFrame into a list of dictionaries
# Each dictionary represents a document to be indexed
documents = df.to_dict(orient="records")# Define a function to generate actions for bulk API
def generate_bulk_actions(documents):for doc in documents:yield {"_index": "imdb_movies","_source": doc,}# Use the bulk helper to insert documents, 200 at a time
start_time = time.time()
helpers.bulk(es, generate_bulk_actions(documents), chunk_size=200)
end_time = time.time()print(f"The function took {end_time - start_time} seconds to run")
我们可以在 Kibana 中进行查看:
我们需要等一定的时间来完成上面的摄取工作。值得注意的是:在上面的代码中我把 chunk_size 设置为 20。这个是为了避免 "Connection timeout" 错误。如果我们把这个值设置很大,那么摄取的时间可能过长,那么就会发生 "Connection timeout" 这样的错误。我们在批量处理时,选择比较少的文档来完成摄取工作。有关如何设置这个 timeout 的时间,我们可以参考文章 “在 Elasticsearch 中扩展 ML 推理管道:如何避免问题并解决瓶颈”。
针对我的电脑,它花费了如下的时间来完成 10,178 个文档的摄取:
The function took 1292.8102316856384 seconds to run
这个将近20分钟。
缩小 ELSER 和 e5 模型
我们不需要大量的模型分配来进行测试查询,因此我们将每个模型分配缩小到 1 个
for model_id in [".elser_model_2","my-e5-model"]:result = es.perform_request("POST",f"/_ml/trained_models/{model_id}/deployment/_update",headers={"content-type": "application/json", "accept": "application/json"},body={"number_of_allocations": 1},)
Retriever 测试
我们将使用搜索输入 clueless slackers 在数据集中的 overview 字段(文本或嵌入)中搜索电影
请随意将下面的 movie_search 变量更改为其他内容
movie_search = "clueless slackers"
Standard - 搜索所有文本! - bm25
response = es.search(index="imdb_movies",body={"query": {"match": {"overview": movie_search}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")
kNN-搜索所有密集向量!
response = es.search(index="imdb_movies",body={"retriever": {"knn": {"field": "overview_dense","query_vector_builder": {"text_embedding": {"model_id": "my-e5-model","model_text": movie_search,}},"k": 5,"num_candidates": 5,}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")
text_expansion - 搜索所有稀疏向量! - elser
response = es.search(index="imdb_movies",body={"retriever": {"standard": {"query": {"text_expansion": {"overview_sparse": {"model_id": ".elser_model_2","model_text": movie_search,}}}}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")
rrf — 将所有事物结合起来!
response = es.search(index="imdb_movies",body={"retriever": {"rrf": {"retrievers": [{"standard": {"query": {"term": {"overview": movie_search}}}},{"knn": {"field": "overview_dense","query_vector_builder": {"text_embedding": {"model_id": "my-e5-model","model_text": movie_search,}},"k": 5,"num_candidates": 5,}},{"standard": {"query": {"text_expansion": {"overview_sparse": {"model_id": ".elser_model_2","model_text": movie_search,}}}}},],"window_size": 5,"rank_constant": 1,}},"size": 3,"fields": ["names", "overview"],"_source": False,},
)for hit in response["hits"]["hits"]:print(f"{hit['fields']['names'][0]}\n- {hit['fields']['overview'][0]}\n")
所有的源码可以在地址 elasticsearch-labs/supporting-blog-content/introducing-retrievers/retrievers_intro_notebook.ipynb at main · liu-xiao-guo/elasticsearch-labs · GitHub
下载。
相关文章:
Elasticsearch:Retrievers 介绍 - Python Jupyter notebook
在今天的文章里,我是继上一篇文章 “Elasticsearch:介绍 retrievers - 搜索一切事物” 来使用一个可以在本地设置的 Elasticsearch 集群来展示 Retrievers 的使用。在本篇文章中,你将学到如下的内容: 从 Kaggle 下载 IMDB 数据集…...
5 webSocket
webSockets 简介 什么是 websocket webSockets 是一种先进的技术;它可以在用户的浏览器和服务器之间打开交互式通信会话;使用此 API,您可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应 websocket 是一种网络通信协议,是HTML5开始提供的一种在单…...
PD芯片诱骗取电电压给后端小家电用电:LDR6328
在智能家居浪潮的推动下,小家电作为日常生活中不可或缺的一部分,其供电方式的创新与优化正逐步成为行业关注的焦点。随着快充技术的普及,特别是Power Delivery(PD)协议的广泛应用,一种新型供电模式——利用…...
深入解析Linux文件权限管理:掌握`chmod`和`chown`命令
深入解析Linux文件权限管理:掌握chmod和chown命令 深入解析Linux文件权限管理:掌握chmod和chown命令 大纲:摘要:内容: 1. 引言2. 理解文件权限3. 使用chmod命令4. 使用chown命令5. 综合应用6. 常见问题与解决方案7. 结…...
3.Implementing Controllers
Implementing Controllers 控制器提供了对应用程序行为的访问,这些行为通常通过一个服务接口来定义。控制器解释用户输入,并将其转换为由视图展示给用户的模型。Spring 以非常抽象的方式实现了控制器,使得你能够创建各种各样的控制器。 Spr…...
如何分清楚常见的 Git 分支管理策略Git Flow、GitHub Flow 和 GitLab Flow
Git Flow、GitHub Flow 和 GitLab Flow 是几种常见的 Git 分支管理策略,它们帮助开发团队更高效地管理代码库和协同开发。 Git Flow Git Flow 是一种功能强大的分支管理模型,由 Vincent Driessen 提出,适用于发布周期较长、需要严格管理发布…...
Java垃圾收集器选择与优化策略
1.垃圾收集算法有哪些,可以聊一下吗? 如何确定一个对象是垃圾? 要想进行垃圾回收,得先知道什么样的对象是垃圾。 1.1 引用计数法 对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾。如果一个对象没有任何指针对其引用,它就是垃圾。 弊端:如果…...
django命令
Django 的命令行工具 django-admin(或 manage.py 中的 manage 函数)提供了一系列的命令,用于执行各种管理任务。 1. check: 检查项目的 full 路径,确保没有错误配置。 2. compilemessages: 编译 .po 文件中的翻译,生…...
23种设计模式之命令模式
命令模式 1、定义 命令模式:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作 2、命令模式结构 Command(抽象命令类):一般是…...
esp8266模块(1)
1WiFi的两种模式 1AP模式:ESP8266模块充当一个无线接入点,类似于一个路由器。(如手机开热点) 2Station模式(sta):ESP8266模块作为客户端连接到一个现有的WiFi网络。(如路由器&#…...
LDR6020:重塑iPad一体式有线键盘体验的创新力量
在移动办公与娱乐日益融合的时代,iPad凭借其强大的性能和便携性,成为了众多用户不可或缺的生产力工具。然而,为了进一步提升iPad的使用体验,一款高效、便捷的键盘成为了不可或缺的配件。今天,我们要介绍的,…...
ArcGIS Pro SDK (九)几何 9 立方贝塞尔线段
ArcGIS Pro SDK (九)几何 9 立方贝塞尔线段 文章目录 ArcGIS Pro SDK (九)几何 9 立方贝塞尔线段1 构建立方贝塞尔线段 - 从坐标2 构建立方贝塞尔线段 - 从地图点3 构造立方贝塞尔线段 - 从映射点的枚举4 立方贝塞尔线段生成器属性…...
c语言之 *指针与 **指针
*n 一级指针: &nn*n自身地址指向地址指向地址值 **s 二级指针: &ss*s**s自身地址一级指针地址一级指针指向地址一级指针指向地址值 CHILD *walk, *next, *tmp_child, **scan;next walk->next scan &walk->next; while (*scan) { …...
navicat 导入 sql 遇到的问题
错误1 [Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near SET FOREIGN_KEY_CHECKS 0;DROP TABLE IF EXISTS tmp_tables; CREATE TABLE at line 1 [Err] &…...
压缩pdf大小的方法 指定大小软件且清晰
在数字化时代,pdf文件因其良好的兼容性和稳定性,已成为文档分享的主流格式。然而,高版本的pdf文件往往体积较大,传输和存储都相对困难。本文将为您详细介绍几种简单有效的方法,帮助您减小pdf文件的大小,让您…...
PHP上门按摩专业版防东郊到家系统源码小程序
💆♀️【尊享级体验】上门按摩专业版,告别东郊到家,解锁全新放松秘籍!🏠✨ 🔥【开篇安利,告别传统束缚】🔥 亲们,是不是厌倦了忙碌生活中的疲惫感?想要享…...
从微软发iPhone,聊聊企业设备管理
今天讲个上周的旧闻,微软给员工免费发iPhone。其实上周就有很多朋友私信问我,在知乎上邀请我回答相关话题,今天就抽点时间和大家一起聊聊这事。我不想讨论太多新闻本身,而是更想聊聊事件的主要原因——微软企业设备管理࿰…...
抖音/腾讯/百度ocpm深度回传如何操作?广告投放双出价的投放技巧?
要实现抖音、腾讯和百度的OCPM(Optimized Cost Per Mille)深度回传,可以通过借助第三方平台,例如(转化宝)实现广告数据精准回传,如此之外,在广告投放过程中还需要注重这些方面。 转化…...
DPKG(Debian / Ubuntu包管理工具)的深入探索与使用
DPKG(Debian / Ubuntu包管理工具)的深入探索与使用 在Linux世界中,特别是基于Debian及其衍生系统(如Ubuntu)的环境中,dpkg是管理Debian软件包(.deb文件)的核心工具。它不仅用于安装…...
Godot学习笔记2——GDScript变量与函数
Godot使用的编程语言是GDS,语法上与python有些类似。 一、代码编写界面 在新建的Godot项目中,点击“创建根节点”中的“其他节点”,选择“Node”。 点击场景界面右上角的绿色加号,路径处重新命名,模板选择“Empty”&…...
golang开发环境搭建与踩坑记录
文章目录 一、安装下载1、go环境2、ide 二、基本使用1、运行2、结构体与方法函数指针3、闭包4、指针5、map6、接口7、异常 三、包管理1、go mod语法2、项目下载所有依赖 一、安装下载 1、go环境 下载地址:https://go.dev/dl/ 或者:https://golang.goog…...
单机、集群、分布式服务器比较:
1. 单机服务器的瓶颈: 单机服务器:一台服务器独立运行一个工程所需的全部的业务模块 受限于服务器硬件资源,所承受用户并发量受限,32位linux操作系统最大并发量为两万任一模块的变动和修改,都会导致整个项目代码重新编…...
NoSql选择题解
1. (单选题)以下不属于ACID原则的是( )。 A. 相对性 B. 原子性 C. 隔离性 D. 持久性 正确答案: A :相对性; 2. (单选题)以下NoSQL数据库中,哪个是内存数据库()。 A. Bigtable B. Redis C. Hbase D. MongoDB 正确答案: B :Redis; …...
国内新能源汽车芯片自给,承认差距,任重道远
【科技明说 | 科技热点关注】 据近日工信部电子五所元器件与材料研究院高级副院长罗道军表示,中国拥有最大的新能源车产能,芯片用量也是越来越多。但是芯片的自给率目前不到10%,是结构性的短缺。 中国拥有最大新能源车产能&#…...
反爬虫策略中的IP地址轮换如何实现?挑战与对策
当今互联网时代,各类网站、网络平台背后隐藏着大量数据,广告数据收集、市场数据收集都需要依托爬虫技术,但很多网站通过反爬虫技术限制或屏蔽爬虫的访问,这给数据收集带来不小的挑战。 为了规避这些反爬虫策略,开发人…...
AUTOSAR CAN网络Bus Load Reduction Mechanism
1. Bus Load Reduction Mechanism有什么用 根据AUTOSAR CanNM规范,NM PDU的发送周期由参数CanNmMsgCycleTime决定,并且属于同一个网络簇的所有NM节点该参数必须相同。如果不采取任何行动,这将导致总线负载问题,这取决于网络管理集群成员的数量。即使通过节点特定的定时参数…...
【LeetCode力扣】007. 整数反转(Python)
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号)。 示例 1: 输入…...
大数据之写入Doris数据问题
1. 解决Key columns should be a ordered prefix of the schema. KeyColumns[1] (starts from zero) is xxx, but 背景 create table if not exists XXX ( fathercorp varchar(50), id decimalv3(38,0) ) ENGINEOLAP UNIQUE KEY(id) COMMENT xxxx DISTRIBUTED BY HASH(id) BUC…...
HTML+echarts.js实现的炫酷金色风格可视化组件
模板下载地址: 炫酷金色风格可视化组件 (bootstrapmb.com)https://www.bootstrapmb.com/item/14888 一款炫酷金色风格可视化组件,统计图表使用Echarts.js,整体风格采用金黄色看起来很大气,设计是通用型的,可以用作任…...
【BUG】已解决: KeyboardInterrupt
已解决: KeyboardInterrupt 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武汉城市开发者社区主理人 擅长.net、C…...
做网站后有人抢注品牌关键字/seo站长综合查询
应用篇:qt写入版本号应用篇:qt写入版本号创建.rc文件在工程文件中载入.rc文件转载需注明出处应用篇:qt写入版本号 在软件开发及交付的过程中,常常需要对已经发布的软件进行技术维护和bug追踪,而这个恰恰依赖于工程师良…...
肃宁县网站建设/图片外链
理解的作文1000字理解在字典里是指领会,明白道理及事物的规律。当然我的“理解”与这字典里的理解意义相同;但在这里——我所要理解的却是我以前一直无法懂的那个词,虽然我也曾经写过它,夸过它;但写出来的全都不是肺腑…...
wordpress 缩略图地址/seo排名点击器原理
作者: 中国科学院大气物理研究所 律成林 ————————————————2023年1月26日追加内容———————————————— 使用m_vec时的注意事项: 在使用m_vec函数时,输入数据要用双精度数组(double)。如果是单精度数组(sing…...
WordPress自定义json接口/肇庆seo优化
日志统计 #尺取法 #vector容器 #全局变量能开更大的空间哦~ 题目 小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞"。 现在小明想统计有哪…...
企业为什么融资/seo优化内容
一、什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用。 下面我们就对OGNL这5个作用进行讲解 1、存取对象的任意属性,简单说就是对javabean进行操作(重要) 2、调用对象方法。 3、调用类的静态方法 4、索引数组元素 5、操作集…...