Elasticsearch基础操作入门

阅前准备知识

学习 Elasticsearch (简称 ES) 的查询方式,建议从以下几个步骤入手:

  1. 理解 Elasticsearch 的基础概念

首先要了解 Elasticsearch 的核心概念,例如:

  • Index(索引):相当于数据库中的表,每个索引中存储着类似类型的数据。
  • Document(文档):相当于数据库中的一行数据,每个文档以 JSON 格式存储。
  • Shard(分片)和 Replica(副本):理解分片和副本有助于掌握数据的分布和冗余策略。
  1. 学习 DSL(Domain-Specific Language)查询语法

ES 提供了一种基于 JSON 的查询语言,称为 DSL。学习这部分时,主要包括:

  • 基本查询:如 matchtermrange 查询。
  • 布尔查询:如 mustshouldfilter 这些条件组合。
  • 聚合查询:如 terms 聚合、avg 聚合等,用于统计数据。

示例:
查询包含某个词的文档:

{"query": {"match": {"field_name": "keyword"}}
}
  1. 深入掌握过滤和分页

查询通常会使用过滤器来优化性能,学会如何通过 filter 语句来减少不必要的计算。

{"query": {"bool": {"filter": [{"term": {"status": "active"}}]}}
}
  1. 理解全文检索和评分机制

Elasticsearch 的优势在于它的全文检索能力,理解倒排索引(Inverted Index)和评分机制(Relevance Scoring),可以帮助你构建更加精准的查询。

  1. 学习聚合(Aggregations)

聚合查询是 Elasticsearch 强大的功能之一,能够进行复杂的数据统计和分析:

  • terms 聚合:统计字段的不同值的数量。
  • date_histogram 聚合:按日期区间统计数据。
  • nested 聚合:处理嵌套对象的聚合查询。

示例: 按字段统计每个值的文档数量:

{"aggs": {"group_by_status": {"terms": {"field": "status"}}}
}

Elasticsearch 交互格式

所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。

一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:

curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'

< > 标记的部件:

VERB适当的 HTTP 方法谓词 : GETPOSTPUTHEAD 或者 DELETE
PROTOCOLhttp 或者 https(如果你在 Elasticsearch 前面有一个 https 代理)
HOSTElasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。
PORT运行 Elasticsearch HTTP 服务的端口号,默认是 9200
PATHAPI 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats_nodes/stats/jvm
QUERY_STRING任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)
BODY一个 JSON 格式的请求体 (如果请求需要的话)

测试 Elasticsearch 是否启动成功

curl 'http://localhost:9200/?pretty'

计算集群中文档的数量

curl -X GET "localhost:9200/_count?pretty" -H 'Content-Type: application/json' -d'
{"query": {"match_all": {}}
}
'

索引员工文档

第一个业务需求是存储员工数据。 这将会以 员工文档 的形式存储:一个文档代表一个员工。存储数据到 Elasticsearch 的行为叫做 索引 ,但在索引一个文档之前,需要确定将文档存储在哪里。

一个 Elasticsearch 集群可以 包含多个 索引 ,相应的每个索引可以包含多个 类型 。 这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性

Index Versus Index Versus Index

你也许已经注意到 索引 这个词在 Elasticsearch 语境中有多种含义, 这里有必要做一些说明:

索引(名词):

如前所述,一个 索引 类似于传统关系数据库中的一个 数据库 ,是一个存储关系型文档的地方。 索引 (index) 的复数词为 indicesindexes

索引(动词):

索引一个文档 就是存储一个文档到一个 索引 (名词)中以便被检索和查询。这非常类似于 SQL 语句中的 INSERT 关键词,除了文档已存在时,新文档会替换旧文档情况之外。

倒排索引:

关系型数据库通过增加一个 索引 比如一个 B树(B-tree)索引 到指定的列上,以便提升数据检索速度。Elasticsearch 和 Lucene 使用了一个叫做 倒排索引 的结构来达到相同的目的。

+ 默认的,一个文档中的每一个属性都是 被索引 的(有一个倒排索引)和可搜索的。一个没有倒排索引的属性是不能被搜索到的。我们将在 倒排索引 讨论倒排索引的更多细节。

对于员工目录,我们将做如下操作:

  • 每个员工索引一个文档,文档包含该员工的所有信息。
  • 每个文档都将是 employee 类型
  • 该类型位于 索引 megacorp 内。
  • 该索引保存在我们的 Elasticsearch 集群中。

实践中这非常简单(尽管看起来有很多步骤),我们可以通过一条命令完成所有这些动作:

PUT /megacorp/employee/1
{"first_name" : "John","last_name" :  "Smith","age" :        25,"about" :      "I love to go rock climbing","interests": [ "sports", "music" ]
}
或
curl -X PUT "localhost:9200/megacorp/employee/1?pretty" -H 'Content-Type: application/json' -d'
{"first_name" : "John","last_name" :  "Smith","age" :        25,"about" :      "I love to go rock climbing","interests": [ "sports", "music" ]
}
'

请求体 —— JSON 文档 —— 包含了这位员工的所有详细信息,他的名字叫 John Smith ,今年 25 岁,喜欢攀岩。

PUT /megacorp/employee/2
{"first_name" :  "Jane","last_name" :   "Smith","age" :         32,"about" :       "I like to collect rock albums","interests":  [ "music" ]
}PUT /megacorp/employee/3
{"first_name" :  "Douglas","last_name" :   "Fir","age" :         35,"about":        "I like to build cabinets","interests":  [ "forestry" ]
}或curl -X PUT "localhost:9200/megacorp/employee/2?pretty" -H 'Content-Type: application/json' -d'
{"first_name" :  "Jane","last_name" :   "Smith","age" :         32,"about" :       "I like to collect rock albums","interests":  [ "music" ]
}
'
curl -X PUT "localhost:9200/megacorp/employee/3?pretty" -H 'Content-Type: application/json' -d'
{"first_name" :  "Douglas","last_name" :   "Fir","age" :         35,"about":        "I like to build cabinets","interests":  [ "forestry" ]
}
'

检索文档

目前我们已经在 Elasticsearch 中存储了一些数据, 接下来就能专注于实现应用的业务需求了。第一个需求是可以检索到单个雇员的数据。

这在 Elasticsearch 中很简单。简单地执行 一个 HTTP GET 请求并指定文档的地址——索引库、类型和ID。 使用这三个信息可以返回原始的 JSON 文档:

GET /megacorp/employee/1curl -X GET "localhost:9200/megacorp/employee/1?pretty"

返回结果包含了文档的一些元数据,以及 _source 属性,内容是 John Smith 雇员的原始 JSON 文档:

{"_index" :   "megacorp","_type" :    "employee","_id" :      "1","_version" : 1,"found" :    true,"_source" :  {"first_name" :  "John","last_name" :   "Smith","age" :         25,"about" :       "I love to go rock climbing","interests":  [ "sports", "music" ]}
}

轻量搜索

一个 GET 是相当简单的,可以直接得到指定的文档。 现在尝试点儿稍微高级的功能,比如一个简单的搜索!

第一个尝试的几乎是最简单的搜索了。我们使用下列请求来搜索所有雇员:

GET /megacorp/employee/_searchcurl -X GET "localhost:9200/megacorp/employee/_search?pretty"

可以看到,我们仍然使用索引库 megacorp 以及类型 employee,但与指定一个文档 ID 不同,这次使用 _search 。返回结果包括了所有三个文档,放在数组 hits 中。一个搜索默认返回十条结果。

{"took":      6,"timed_out": false,"_shards": { ... },"hits": {"total":      3,"max_score":  1,"hits": [{"_index":         "megacorp","_type":          "employee","_id":            "3","_score":         1,"_source": {"first_name":  "Douglas","last_name":   "Fir","age":         35,"about":       "I like to build cabinets","interests": [ "forestry" ]}},{"_index":         "megacorp","_type":          "employee","_id":            "1","_score":         1,"_source": {"first_name":  "John","last_name":   "Smith","age":         25,"about":       "I love to go rock climbing","interests": [ "sports", "music" ]}},{"_index":         "megacorp","_type":          "employee","_id":            "2","_score":         1,"_source": {"first_name":  "Jane","last_name":   "Smith","age":         32,"about":       "I like to collect rock albums","interests": [ "music" ]}}]}
}

注意:返回结果不仅告知匹配了哪些文档,还包含了整个文档本身:显示搜索结果给最终用户所需的全部信息。

接下来,尝试下搜索姓氏为 Smith 的雇员。为此,我们将使用一个 高亮 搜索,很容易通过命令行完成。这个方法一般涉及到一个 查询字符串query-string) 搜索,因为我们通过一个URL参数来传递查询信息给搜索接口:

GET /megacorp/employee/_search?q=last_name:Smithcurl -X GET "localhost:9200/megacorp/employee/_search?q=last_name:Smith&pretty"

我们仍然在请求路径中使用 _search 端点,并将查询本身赋值给参数 q= 。返回结果给出了所有的 Smith:

{..."hits": {"total":      2,"max_score":  0.30685282,"hits": [{..."_source": {"first_name":  "John","last_name":   "Smith","age":         25,"about":       "I love to go rock climbing","interests": [ "sports", "music" ]}},{..."_source": {"first_name":  "Jane","last_name":   "Smith","age":         32,"about":       "I like to collect rock albums","interests": [ "music" ]}}]}
}

使用查询表达式搜索

Query-string 搜索通过命令非常方便地进行临时性的即席搜索 ,但它有自身的局限性(参见 轻量 搜索 )。Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。

领域特定语言 (DSL), 使用 JSON 构造了一个请求。我们可以像这样重写之前的查询所有名为 Smith 的搜索 :

GET /megacorp/employee/_search
{"query" : {"match" : {"last_name" : "Smith"}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"query" : {"match" : {"last_name" : "Smith"}}
}
'

返回结果与之前的查询一样,但还是可以看到有一些变化。其中之一是,不再使用 query-string 参数,而是一个请求体替代。这个请求使用 JSON 构造,并使用了一个 match 查询(属于查询类型之一,后面将继续介绍)。

更复杂的搜索

现在尝试下更复杂的搜索。 同样搜索姓氏为 Smith 的员工,但这次我们只需要年龄大于 30 的。查询需要稍作调整,使用过滤器 filter ,它支持高效地执行一个结构化查询。

GET /megacorp/employee/_search
{"query" : {"bool": {"must": {"match" : {"last_name" : "smith" }},"filter": {"range" : {"age" : { "gt" : 30 } }}}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"query" : {"bool": {"must": {"match" : {"last_name" : "smith" }},"filter": {"range" : {"age" : { "gt" : 30 } }}}}
}
'

1、这部分与我们之前使用的 match 查询 一样。

2、这部分是一个 range 过滤器 , 它能找到年龄大于 30 的文档,其中 gt 表示_大于_(great than)。

目前无需太多担心语法问题,后续会更详细地介绍。只需明确我们添加了一个 过滤器 用于执行一个范围查询,并复用之前的 match 查询。现在结果只返回了一名员工,叫 Jane Smith,32 岁。

{..."hits": {"total":      1,"max_score":  0.30685282,"hits": [{..."_source": {"first_name":  "Jane","last_name":   "Smith","age":         32,"about":       "I like to collect rock albums","interests": [ "music" ]}}]}
}

全文搜索

截止目前的搜索相对都很简单:单个姓名,通过年龄过滤。现在尝试下稍微高级点儿的全文搜索——一项 传统数据库确实很难搞定的任务。

搜索下所有喜欢攀岩(rock climbing)的员工:

GET /megacorp/employee/_search
{"query" : {"match" : {"about" : "rock climbing"}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"query" : {"match" : {"about" : "rock climbing"}}
}
'

显然我们依旧使用之前的 match 查询在about 属性上搜索 “rock climbing” 。得到两个匹配的文档:

{..."hits": {"total":      2,"max_score":  0.16273327,"hits": [{..."_score":         0.16273327, "_source": {"first_name":  "John","last_name":   "Smith","age":         25,"about":       "I love to go rock climbing","interests": [ "sports", "music" ]}},{..."_score":         0.016878016, "_source": {"first_name":  "Jane","last_name":   "Smith","age":         32,"about":       "I like to collect rock albums","interests": [ "music" ]}}]}
}

相关性得分

Elasticsearch 默认按照相关性得分排序,即每个文档跟查询的匹配程度。第一个最高得分的结果很明显:John Smith 的 about 属性清楚地写着 “rock climbing” 。

但为什么 Jane Smith 也作为结果返回了呢?原因是她的 about 属性里提到了 “rock” 。因为只有 “rock” 而没有 “climbing” ,所以她的相关性得分低于 John 的。

这是一个很好的案例,阐明了 Elasticsearch 如何 全文属性上搜索并返回相关性最强的结果。Elasticsearch中的 相关性 概念非常重要,也是完全区别于传统关系型数据库的一个概念,数据库中的一条记录要么匹配要么不匹配。

短语搜索

找出一个属性中的独立单词是没有问题的,但有时候想要精确匹配一系列单词或者_短语_ 。 比如, 我们想执行这样一个查询,仅匹配同时包含 “rock” “climbing” ,并且 二者以短语 “rock climbing” 的形式紧挨着的雇员记录。

为此对 match 查询稍作调整,使用一个叫做 match_phrase 的查询:

GET /megacorp/employee/_search
{"query" : {"match_phrase" : {"about" : "rock climbing"}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"query" : {"match_phrase" : {"about" : "rock climbing"}}
}
'

毫无悬念,返回结果仅有 John Smith 的文档。

{..."hits": {"total":      1,"max_score":  0.23013961,"hits": [{..."_score":         0.23013961,"_source": {"first_name":  "John","last_name":   "Smith","age":         25,"about":       "I love to go rock climbing","interests": [ "sports", "music" ]}}]}
}

高亮搜索

许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。在 Elasticsearch 中检索出高亮片段也很容易。

再次执行前面的查询,并增加一个新的 highlight 参数:

GET /megacorp/employee/_search
{"query" : {"match_phrase" : {"about" : "rock climbing"}},"highlight": {"fields" : {"about" : {}}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"query" : {"match_phrase" : {"about" : "rock climbing"}},"highlight": {"fields" : {"about" : {}}}
}
'

当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分。这个部分包含了 about 属性匹配的文本片段,并以 HTML 标签 <em></em> 封装:

{..."hits": {"total":      1,"max_score":  0.23013961,"hits": [{..."_score":         0.23013961,"_source": {"first_name":  "John","last_name":   "Smith","age":         25,"about":       "I love to go rock climbing","interests": [ "sports", "music" ]},"highlight": {"about": ["I love to go <em>rock</em> <em>climbing</em>" ]}}]}
}

分析

终于到了最后一个业务需求:支持管理者对员工目录做分析。 Elasticsearch 有一个功能叫聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。

举个例子,挖掘出员工中最受欢迎的兴趣爱好:

GET /megacorp/employee/_search
{"aggs": {"all_interests": {"terms": { "field": "interests" }}}
}
或
curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"aggs": {"all_interests": {"terms": { "field": "interests" }}}
}
'

暂时忽略掉语法,直接看看结果:

{..."hits": { ... },"aggregations": {"all_interests": {"buckets": [{"key":       "music","doc_count": 2},{"key":       "forestry","doc_count": 1},{"key":       "sports","doc_count": 1}]}}
}

可以看到,两位员工对音乐感兴趣,一位对林业感兴趣,一位对运动感兴趣。这些聚合的结果数据并非预先统计,而是根据匹配当前查询的文档即时生成的。如果想知道叫 Smith 的员工中最受欢迎的兴趣爱好,可以直接构造一个组合查询:

GET /megacorp/employee/_search
{"query": {"match": {"last_name": "smith"}},"aggs": {"all_interests": {"terms": {"field": "interests"}}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"query": {"match": {"last_name": "smith"}},"aggs": {"all_interests": {"terms": {"field": "interests"}}}
}
'

all_interests 聚合已经变为只包含匹配查询的文档:

  ..."all_interests": {"buckets": [{"key": "music","doc_count": 2},{"key": "sports","doc_count": 1}]}

聚合还支持分级汇总 。比如,查询特定兴趣爱好员工的平均年龄:

GET /megacorp/employee/_search
{"aggs" : {"all_interests" : {"terms" : { "field" : "interests" },"aggs" : {"avg_age" : {"avg" : { "field" : "age" }}}}}
}curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{"aggs" : {"all_interests" : {"terms" : { "field" : "interests" },"aggs" : {"avg_age" : {"avg" : { "field" : "age" }}}}}
}
'

得到的聚合结果有点儿复杂,但理解起来还是很简单的:

  ..."all_interests": {"buckets": [{"key": "music","doc_count": 2,"avg_age": {"value": 28.5}},{"key": "forestry","doc_count": 1,"avg_age": {"value": 35}},{"key": "sports","doc_count": 1,"avg_age": {"value": 25}}]}

输出基本是第一次聚合的加强版。依然有一个兴趣及数量的列表,只不过每个兴趣都有了一个附加的 avg_age 属性,代表有这个兴趣爱好的所有员工的平均年龄。

即使现在不太理解这些语法也没有关系,依然很容易了解到复杂聚合及分组通过 Elasticsearch 特性实现得很完美,能够提取的数据类型也没有任何限制。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux学习】(3)Linux的基本指令操作

前言 配置Xshell登录远程服务器Linux的基本指令——man、cp、mv、alias&which、cat&more&less、head&tail、date、cal、find、grep、zip&tar、bc、unameLinux常用热键 一、配置Xshell登录远程服务器 以前我们登录使用指令&#xff1a; ssh 用户名你的公网…

gorm.io/sharding改造:赋能单表,灵活支持多分表策略(下)

背景 分表组件改造的背景&#xff0c;我在这篇文章《gorm.io/sharding改造&#xff1a;赋能单表&#xff0c;灵活支持多分表策略&#xff08;上&#xff09;》中已经做了详细的介绍——这个组件不支持单表多个分表策略&#xff0c;为了突破这个限制做的改造。 在上一篇文章中&…

机器学习基础:算法如何让 AI 自我学习

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 AI工具集1&#xff1a;大厂AI工具【共23款…

vue3+vue-baidu-map-3x 实现地图定位

文档地址&#xff1a;一个是2一个是3 https://dafrok.github.io/vue-baidu-map/#/zh/index vue-baidu-map-3x 1.首先要到百度地图开放平台上建一个账号&#xff0c;如果有百度账号可以直接登录百度地图-百万开发者首选的地图服务商,提供专属的行业解决方案 2.点击控制台&am…

ThreadLocal内存泄漏面试题

一、ThreadLocal内部结构 首先更好的说明ThreadLocal内存泄露的场景&#xff0c;以及具体的原因&#xff0c;先来了解下ThreadLocal的内部结构&#xff0c;如图1所示。 可以看到&#xff0c;ThreadLocal对象是存储在每个Thread线程内部的ThreadLocalMap中的&#xff0c;并且在…

行列式-常山赵子龙

终于知道这类题怎么写了 两个条件都要用到 要计算&#xff0c;减少直觉

【加密系统】华企盾DSC服务台提示:请升级服务器,否则可能导致客户端退回到旧服务器的版本

华企盾DSC服务台提示&#xff1a;请升级服务器&#xff0c;否则可能导致客户端退回到旧服务器的版本 产生的原因&#xff1a;控制台版本比服务器高导致控制台出现报错 解决方案 方法&#xff1a;将控制台回退到原来的使用版本&#xff0c;在控制台负载均衡查看连接该服务器各个…

图像分割-DeepLab

DeepLabV3源码链接&#xff1a;https://github.com/bubbliiiing/deeplabv3-plus-pytorch&#xff08;打不开私信我获取&#xff09; 一、简介 一般的模型如Unet一般用于医学领域&#xff0c;小目标&#xff0c;如细胞分割。 为了增大感受野&#xff08;从而更好的获得全局特征…

LeetCode 18.四数之和

LeetCode 18.四数之和 C 思路&#x1f9d0;&#xff1a; 由题意得&#xff0c;四个数组里面的整数相加需要得到target这个目标值&#xff0c;且结果不能重复&#xff0c;那么我们可以用排序双指针的方式进行解答&#xff0c;将该数组变为升序数组&#xff0c;然后固定左边两个数…

建站工具Halo

建站工具Halo 项目及文档快速体验启动成功 类似wordpress的建站工具&#xff0c;使用java技术栈Springboot开发&#xff0c;对java开发者友好。 项目及文档 https://github.com/halo-dev/halo 快速体验 为了快速体验&#xff0c;直接使用docker compose部署。也可在源码基础…

人工智能+医学

医学影响的内型&#xff1a;(X光片、计算机断层扫描、磁共振成像、超声波&#xff09; ITK snap医学图像读取 医学影像领域常见任务: 图像分类、语义分割、疾病预测、目标检测、图像配准、图像生成(应用少)、图像增强、生成放射学报告。 需要有很强的可解释…

指针进阶(三)(C 语言)

目录 一、回调函数二、快速排序函数 qsort1. qsort() 函数原型2. 使用 qsort() 函数 三、仿照 qsort 函数设计一个可以排序任意类型数组的冒泡函数1. 函数原型2. 函数设计思路 一、回调函数 在 C 语言中&#xff0c;回调函数是一种通过函数指针调用的函数&#xff0c;也就是一…

Spring Boot驱动的植物健康监测革命

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理植物健康系统的相关信息成为必然。开发合适…

软件测试学习笔记丨Selenium学习笔记:常用页面信息对比方法expected_conditions

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/22514 本文为霍格沃兹测试开发学社的学习经历分享&#xff0c;写出来分享给大家&#xff0c;希望有志同道合的小伙伴可以一起交流技术&#xff0c;一起进步~ 说明&#xff1a;本篇博客基于sel…

开拓鸿蒙测试新境界,龙测科技引领自动化测试未来

在当今科技舞台上&#xff0c;鸿蒙 OS 以非凡先进性强势登场&#xff0c;打破传统操作系统格局&#xff0c;为软件测试领域带来全新机遇与艰巨挑战。 一、鸿蒙 OS 的辉煌崛起 &#xff08;一&#xff09;壮丽发展历程与卓越市场地位 鸿蒙 OS 的发展如波澜壮阔的史诗。2023 年…

JavaScript进阶:手写代码挑战(一)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript手写代码篇 #1024程序员节&#xff5c;征文# 在现代Web开发中&#xff0c…

中国移动机器人将投入养老场景;华为与APUS共筑AI医疗多场景应用

AgeTech News 一周行业大事件 华为与APUS合作&#xff0c;共筑AI医疗多场景应用 中国移动展出人形机器人&#xff0c;预计投入养老等场景 作为科技与奥富能签约&#xff0c;共拓智能适老化改造领域 天与养老与香港科技园&#xff0c;共探智慧养老新模式 中山大学合作中国…

[Python学习日记-53] Python 中的正则表达式模块 —— re

[Python学习日记-53] Python 中的正则表达式模块 —— re 简介 re 模块 练习 简介 我们在编程的时候经常会遇到想在一段文字当中找出电话号码、身份证号、身高、年龄之类的信息&#xff0c;就像下面的数据一样 # 文件名&#xff1a;美丽学姐联系方式.txt 姓名 地区 …

微信小程序美团点餐

引言&#xff1a;外卖已经成为了都市人的必备&#xff0c;在无数个来不及&#xff08;懒得&#xff09;做饭的时刻拯救孤单寂寞的胃。美团外卖无疑是外卖届的领头羊&#xff0c;它的很多功能与设计都值得我们学习。本文将从五个方面&#xff0c;对美团外卖展开产品分析&#xf…

【ArcGIS Pro实操第4期】绘制三维地图

【ArcGIS Pro实操第4期】绘制三维地图 ArcGIS Pro绘制三维地图-以DEM高程为例参考 如何使用ArcGIS Pro将栅格数据用三维的形式进行表达&#xff1f;在ArcGIS里可以使用ArcScene来实现&#xff0c;ArcGIS Pro实现原理跟ArcScene一致。由于Esri未来将不再对ArcGIS更新&#xff0c…