Elasticsearch 的搜索功能

Elasticsearch 的搜索功能

建議閱讀順序:

  1. Elasticsearch 入門
  2. Elasticsearch 搜索(本文)
  3. Elasticsearch 搜索高級
  4. Elasticsearch 高級

1. 介紹

使用 Elasticsearch 最終目的是為了實現搜索功能,現在先將文檔添加到索引中,接下來完成搜索的方法。

查詢的分類:

  1. 葉子查詢:葉查詢子句在特定字段中查找特定值,例如 matchtermrange查詢。
    1. 精確查詢:根據精確詞條值查找數據,一般是查找 keyword、數值、日期、boolean 等類型字段。例如:
      • ids:根據文檔 ID 查找文檔
      • range:返回包含指定范圍內的文檔,比如:查詢年齡在 10 到 20 歲的學生信息。
      • term:根據精確值(例如價格、產品 ID 或用戶名)查找文檔。
    2. 全文檢索查詢:利用分詞器對用戶輸入內容分詞,然后去倒排索引庫中匹配。例如:
      • match_query:對一個字段進行全文檢索
      • multi_match_query:對多個字段進行全文檢索
  2. 復合查詢:以邏輯方式組合多個葉子查詢或者更改葉子查詢的行為方式。

1.1 精確查詢

1.1.1 term

語法:

GET /{索引庫名}/_search
{"query": {"term": {"字段名": {"value": "搜索條件"}}}
}

當輸入的搜索條件不是詞條,而是短語時,由于不做分詞,反而搜索不到:

1.1.2 range

語法:

GET /{索引庫名}/_search
{"query": {"range": {"字段名": {"gte": {最小值},"lte": {最大值}}}}
}

range 是范圍查詢,對于范圍篩選的關鍵字有:

  • gte:大于等于
  • gt:大于
  • lte:小于等于
  • lt:小于

1.2 全文檢索

會對搜索條件進行拆分

1.2.1 match

語法:

GET /{索引庫名}/_search
{"query": {"match": {"字段名": "搜索條件"}}
}
1.2.2 multi_match

同時對多個字段搜索,而且多個字段都要滿足,語法:

GET /{索引庫名}/_search
{"query": {"multi_match": {"query": "搜索條件","fields": ["字段1", "字段2"]}}
}

1.3 排序

語法:

GET /indexName/_search
{"query": {"match_all": {}},"sort": [{"排序字段": {"order": "排序方式asc和desc"}}]
}

如果按照商品價格排序:

GET /items/_search
{"query": {"match_all": {}},"sort": [ { "price": { "order": "desc" } } ]
}

1.4 分頁查詢

elasticsearch 默認情況下只返回 top10 的數據。而如果要查詢更多數據就需要修改分頁參數了。

elasticsearch 中通過修改 fromsize 參數來控制要返回的分頁結果:

  • from:從第幾個文檔開始
  • size:總共查詢幾個文檔

語法:

GET /items/_search
{"query": {"match_all": {}},"from": 0, // 分頁開始的位置,默認為0"size": 10,  // 每頁文檔數量,默認10"sort": [ { "price": { "order": "desc" } } ]
}

2. Java Client 實現搜索

2.1 準備

代碼:

@SpringBootTest
public class SearchTest {@Autowiredprivate IItemService itemService;private RestClient restClient = null;private ElasticsearchTransport transport = null;private ElasticsearchClient esClient = null;{// 使用 RestClient 作為底層傳輸對象restClient = RestClient.builder(new HttpHost("192.168.101.68", 9200)).build();ObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new JavaTimeModule());// 使用 Jackson 作為 JSON 解析器transport = new RestClientTransport(restClient, new JacksonJsonpMapper(objectMapper));}// 實現后續操作// TODO@BeforeEachpublic void searchTest() {// 創建客戶端esClient = new ElasticsearchClient(transport);System.out.println(esClient);}@AfterEachpublic void close() throws IOException {transport.close();}}

后續代碼放在代碼的 TODO 處運行即可!!!

2.2 精準查詢

2.2.1 Term 查詢

根據 DSL 語句編寫 java 代碼:

GET /items/_search
{"query": {"term": {"category": { "value": "拉桿箱" }}}
}

代碼:

@Test
public void testTermSearch() throws IOException {SearchResponse<ItemDoc> search = esClient.search(// 搜索索引s -> s.index("items").query(// 精準匹配q -> q.term(t -> t.field("category").value("牛奶"))),// 指定返回類型ItemDoc.class);handleResponse(search);
}
2.2.2 range 查詢
GET /items/_search
{"query": {"range": {"price": { "gte": 100000, "lte": 20 }}}
}

代碼:

@Test
public void testRangeSearch() throws IOException {SearchResponse<ItemDoc> search = esClient.search(// 搜索索引s -> s.index("items").query(// 范圍匹配,price >= 100000 && price < 200000q -> q.range(t -> t.field("price").gte(JsonData.of(100000)).lt(JsonData.of(200000)))),// 指定返回類型ItemDoc.class);

2.3 全文檢索

2.3.1 match 查詢
GET /items/_search
{"query": {"match": {"name": "德國進口純奶"}}
}

代碼:

@Test
public void testMatchSearch() throws IOException {SearchResponse<ItemDoc> search = esClient.search(// 搜索索引s -> s.index("items").query(// 模糊匹配q -> q.match(// 在 name 字段中模糊匹配 "德國進口純奶"t -> t.field("name").query("德國進口純奶"))),// 返回值類型ItemDoc.class);handleResponse(search);
}
2.3.2 multi_match 查詢
GET /items/_search
{"query": {"multi_match": {"query": "筆記本","fields": ["name", "category"]}}
}

代碼:

@Test
public void testMultiMatchSearch() throws IOException {SearchResponse<ItemDoc> search = esClient.search(// 搜索索引s -> s.index("items").query(// 多字段模糊匹配q -> q.multiMatch(// 匹配字關鍵字t -> t.query("筆記本")// 匹配字段.fields("name", "category"))),// 指定返回類型ItemDoc.class);handleResponse(search);
}

2.4 排序和分頁

GET /items/_search
{"query": {"multi_match": {"query": "綠色拉桿箱","fields": ["name","category"]}},"sort": [{ "price": { "order": "asc" } }],"size": 20,"from": 0
}

代碼:

@Test
public void testSortSearch() throws IOException {SearchResponse<ItemDoc> search = esClient.search(// 搜索索引s -> s.index("items")// 查詢條件.query(q -> q.multiMatch(// 匹配字段m -> m.query("綠色拉桿箱").fields("name", "category")))// 排序規則.sort(s1 -> s1.field(// 排序字段f -> f.field("price")// 排序規則.order(SortOrder.Desc)))// 分頁.from(0).size(10),// 指定返回類型ItemDoc.class);handleResponse(search);
}

3. 復合查詢

3.1 布爾查詢

bool 查詢,即布爾查詢。就是利用邏輯運算來組合一個或多個查詢子句的組合。bool 查詢支持的邏輯運算有:

  1. must:必須匹配每個子查詢,類似 “與”;
  2. should:選擇性匹配子查詢,類似 “或”;
  3. must_not:必須不匹配,不參與算分,類似 “非”;
  4. filter:必須匹配,不參與算分

舉例:

GET /items/_search
{"query": {"bool": {"must": [ {"match": {"name": "手機"}} ],"should": [{"term": {"brand": { "value": "vivo" }}},{"term": {"brand": { "value": "小米" }}}],"must_not": [{"range": {"price": {"gte": 2500}}}]}},"sort": [ { "brand": { "order": "desc" } } ]
}

說明:

  1. 必須條件(must):
    1. 文檔的 name 字段必須包含“手機”。
  2. 可選條件(should):
    1. 文檔的 brand 字段應該是 “vivo” 或者 “小米”。只要滿足其中一個條件即可。
  3. 排除條件(must_not):
    1. 文檔的 price 字段不能大于等于 2500 元。
  4. 過濾條件(filter):
    1. 文檔的 price 字段必須小于等于 1000 元。

當 should 與 must、must_not 同時使用時 should 會失效,需要指定 minimum_should_match。

3.2 盡量使用 filter

出于性能考慮,與搜索關鍵字無關的查詢盡量采用 must_not 或 filter 邏輯運算,避免參與相關性算分(如:下拉菜單、多級菜單等)。

比如,要搜索 手機,但品牌必須是 華為,價格必須是 900~1599,那么可以這樣寫:

GET /items/_search
{"query": {"bool": {"must": [{"match": {"name": "手機"}}],"filter": [{"term": {"brand": { "value": "華為" }}},{"range": {"price": {"gte": 90000, "lte": 159900}}}]}}
}

3.3 Java Client

@Test
void testBoolQuery() throws Exception {//構建請求SearchRequest.Builder builder = new SearchRequest.Builder();//設置索引builder.index("items");//設置查詢條件SearchRequest.Builder searchRequestBuilder = builder.query(// bool 查詢,多條件匹配q -> q.bool(// must 連接b -> b.must(m -> m.match(// name 檢索mm -> mm.field("name").query("手機"))).should(s1 -> s1.term( t -> t.field("brand").value("小米"))).should(s1 -> s1.term(t -> t.field("brand").value("vivo"))).minimumShouldMatch("1")))// 排序·.sort(sort -> sort.field(f -> f.field("brand").order(SortOrder.Asc)));SearchRequest build = searchRequestBuilder.build();//執行請求SearchResponse<ItemDoc> searchResponse = esClient.search(build, ItemDoc.class);//解析結果handleResponse(searchResponse);
}

4. 高亮顯示

4.1 高亮顯示原理

什么是高亮顯示呢?

我們在百度,京東搜索時,關鍵字會變成紅色,比較醒目,這叫高亮顯示。

觀察頁面源碼,你會發現兩件事情:

  • 高亮詞條都被加了 <em> 標簽
  • <em> 標簽都添加了紅色樣式

因此實現高亮的思路就是:

  • 用戶輸入搜索關鍵字搜索數據
  • 服務端根據搜索關鍵字到 elasticsearch 搜索,并給搜索結果中的關鍵字詞條添加 html 標簽
  • 前端提前給約定好的 html 標簽添加 CSS 樣式

4.2 實現高亮

語法:

GET /{索引庫名}/_search
{"query": {"match": {"搜索字段": "搜索關鍵字"}},"highlight": {"fields": {"高亮字段名稱": {"pre_tags": "<em>","post_tags": "</em>"}},"require_field_match": "true"}
}

注意

  • 搜索必須有查詢條件,而且是全文檢索類型的查詢條件,例如 match
  • 參與高亮的字段必須是 text 類型的字段;
  • 默認情況下參與高亮的字段要與搜索字段一致,除非添加:required_field_match = false

代碼:

@Test
public void testHighLightSearch() throws Exception {SearchResponse<ItemDoc> search = esClient.search(// 搜索索引s -> s.index("items").query(// 匹配字段q -> q.match(// 匹配字段m -> m.field("name").query("筆記本")))// 高亮.highlight(h -> h.fields("name",	 f -> f)// 高亮標簽,前后綴.preTags("<b style='color:red'>").postTags("</b>")//.requireFieldMatch(false)),ItemDoc.class);long total = search.hits().total().value();System.out.println("total = " + total);List<Hit<ItemDoc>> hits = search.hits().hits();hits.forEach(hit -> {ItemDoc source = hit.source();// 高亮數據Map<String, List<String>> highlight = hit.highlight();List<String> highlightName = highlight.get("name");if(highlightName != null && !highlightName.isEmpty()){String s = highlightName.get(0);source.setName(s);System.out.println("s = " + s);}});
}

5. 數據聚合

5.1 介紹

聚合(aggregations)可以讓我們極其方便的實現對數據的統計、分析、運算。

應用場景:

  1. 對數據進行統計
  2. 在搜索界面顯示符合條件的品牌、分類、規格等信息

聚合常見的有三類:

  1. 桶(Bucket)聚合:用來對文檔做分組
  • TermAggregation:按照文檔字段值分組,例如按照品牌值分組、按照國家分組
  • Date Histogram:按照日期階梯分組,例如一周為一組,或者一月為一組
  1. 度量(Metric)聚合:用以計算一些值,比如:最大值、最小值、平均值等
  • Avg:求平均值
  • Max:求最大值
  • Min:求最小值
  • Stats:同時求 maxminavgsum
  1. 管道(pipeline)聚合:其它聚合的結果為基礎做進一步運算

5.2 Bucket 聚合

5.2.1 語法

例如我們要統計所有商品中共有哪些商品分類,其實就是以分類(category)字段對數據分組。category 值一樣的放在同一組,屬于 Bucket 聚合中的 Term 聚合。

基本語法如下:

GET /items/_search
{"size": 0, "aggs": {"category_agg": {"terms": {"field": "category","size": 20,"order": { "_count": "desc" }}}}
}

屬性說明:

aggregations:定義聚合

  • category_agg:聚合名稱,自定義,但不能重復

    • terms:聚合的類型,按分類聚合,所以用term

      • field:參與聚合的字段名稱

      • size:希望返回的聚合結果的最大數量

        設置 size 為 0,查詢 0 條數據即結果中不包含文檔,只包含聚合

      • order:對聚合結果排序

5.2.2 多級聚合

同時對品牌分組統計,此時需要按分類統計,按品牌統計,這時需要定義多個桶,如下:

GET /items/_search
{"size": 0, "aggs": {"category_agg": {"terms": { "field": "category", "size": 20 }},"brand_agg":{"terms": { "field": "brand", "size": 20 }}}
}

現在需要統計同一分類下的不同品牌的商品數量,這時就需要對桶內的商品二次聚合,如下:

GET /items/_search
{"aggs" : {"category_agg" : {"aggs" : {"brand_agg" : {"terms" : { "field" : "brand", "size" : 20 }}},"terms" : { "field" : "category", "size" : 20 }}},"size" : 0
}

5.3 帶條件聚合

默認情況下,Bucket 聚合是對索引庫的所有文檔做聚合,例如我們統計商品中所有的品牌,結果如下:


可以看到統計出的品牌非常多。

但真實場景下,用戶會輸入搜索條件,因此聚合必須是對搜索結果聚合。那么聚合必須添加限定條件。

例如,我想知道價格高于 3000 元的手機品牌有哪些,該怎么統計呢?

語法如下:

增加 "query" 標簽。

GET /items/_search
{"query": {"bool": {"filter": [{ "term": { "category": "手機" } },{ "range": { "price": { "gte": 300000 } } }]}}, "size": 0, "aggs": { "brand_agg": { "terms": { "field": "brand", "size": 20 } } }
}

5.4 Metric 聚合

統計了價格高于 3000 的手機品牌,形成了一個個桶。現在我們需要對桶內的商品做運算,獲取每個品牌價格的最小值、最大值、平均值。

語法:

GET /items/_search
{"query": {"bool": {"filter": [{ "term": { "category": "手機" } },{ "range": { "price": { "gte": 300000 } } }]}}, "size": 0, "aggs": {"brand_agg": {"terms": {"field": "brand","size": 20,"order": { "stats_metric.avg": "desc" }},"aggs": { "stats_metric": { "stats": { "field": "price" } } }}}
}

屬性說明:

stats_meric:聚合名稱,自定義名稱

  • stats:聚合類型,stats 是 metric 聚合的一種
    • field:聚合字段,這里選擇 price,統計價格

另外,我們還可以讓聚合按照每個品牌的價格平均值排序:

5.5 Java Client

參考 DSL 語句編寫 Java Client 代碼

@Test
void testAggs() throws Exception {//構建請求SearchRequest.Builder builder = new SearchRequest.Builder();//設置索引名builder.index("items");//設置查詢條件builder.query(q -> q.bool(b -> b.filter(f -> f.term(t -> t.field("category").value("手機"))).filter(f -> f.range(r -> r.field("price").gte(JsonData.of(3000))))));//設置返回數量builder.size(0);//設置聚合builder.aggregations("brand_agg", a -> a.terms(t -> t.field("brand").size(10).order(NamedValue.of("stats_metric.avg", SortOrder.Desc))).aggregations("stats_metric", a1 -> a1.stats(s -> s.field("price"))));SearchRequest build = builder.build();//執行請求SearchResponse<ItemDoc> searchResponse = esClient.search(build, ItemDoc.class);//解析出聚合結果Aggregate brandAgg = searchResponse.aggregations().get("brand_agg");brandAgg.sterms().buckets().array().forEach(bucket -> {String key = bucket.key().stringValue();Long docCount = bucket.docCount();StatsAggregate statsMetric = bucket.aggregations().get("stats_metric").stats();//平均價格Double avg = statsMetric.avg();//最大價格Double max = statsMetric.max();//最小價格Double min = statsMetric.min();log.info("品牌:{},商品數量:{},平均價格:{},最大價格:{},最小價格:{}", key, docCount, avg, max, min);});
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76172.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76172.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76172.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker鏡像拉取失敗

hub.docker.com中提供的docker pull命令在服務器拉取鏡像時報錯Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 這個錯誤通常表明Docker客戶…

EFISH-SBC-RK3576 + 5G模組:無線工業相機與分布式AI質檢?

在智能制造與倉儲物流場景中&#xff0c;傳統有線工業相機存在部署成本高、靈活性差等痛點。?eFish-SBC-RK3576? 通過 ?5G無線傳輸 分布式NPU協同?&#xff0c;實現跨產線、跨工廠的AI質檢系統&#xff0c;檢測效率提升300%&#xff0c;布線復雜度降低90%。 ?1. 系統架構…

AI提示詞編寫方法全解析

在人工智能日益融入生活的當下&#xff0c;如何巧妙編寫提示詞&#xff0c;成為充分發揮AI效能的關鍵。以下為您詳細介紹幾種實用的AI提示詞編寫方法。 角色扮演法&#xff1a;賦予AI獨特身份 角色扮演法旨在讓AI模擬特定角色。當我們渴望AI以歷史人物、虛擬角色的視角進行表…

【docker】docker應用舉例

# Docker創建python項目 ## 1. 準備 Dockerfile 首先,在項目根目錄下創建一個 Dockerfile,用于定義 Docker 鏡像的構建步驟。 # 使用官方 Python 鏡像作為基礎鏡像 FROM python:3.9-slim # 設置工作目錄 WORKDIR /app # 復制項目文件到容器中 COPY . /app # 安裝項目依賴…

【大模型】SpringBoot整合LangChain4j實現RAG檢索實戰詳解

目錄 一、前言 二、LangChain4j 介紹 2.1 什么是LangChain4j 2.2 LangChain4j 主要特點 2.3 Langchain4j 核心組件 三、RAG介紹 3.1 什么是RAG 3.2 RAG工作流程 3.2.1 補充說明 3.3 Embedding模型 3.3.1 RAG實際使用步驟 3.3.2 什么是Embedding 3.3.3 Embedding 技…

基于 Trae 的超輕量級前端架構設計與性能優化實踐

一、技術背景與選型動因 在單頁應用(SPA)復雜度指數級增長的今天&#xff0c;傳統框架在千級列表渲染場景下普遍存在首屏延遲(>1.5s)、內存占用過高(>200MB)等問題。基于對 Webpack Bundle Analyzer 的長期觀察&#xff0c;我們發現核心問題集中在&#xff1a; ? 類組件…

dotnet core web api linux主機公網發布

效果: 發布流程: 創建一個ASP.NET Core Web API 工程 輸入工程名 選擇框架版本為.net 9.0及選擇配置HTTPS和啟用OPENAPI 啟動調試 確認證書

WPS宏開發手冊——JSA語法練習

目錄 系列文章3、JSA語法練習3.1、運算練習3.2、比較練習3.3、if else練習3.4、for 練習3.5、字符串、數組方法練習3.6、語義轉編程練習題 系列文章 使用、工程、模塊介紹 JSA語法 JSA語法練習題 Excel常用Api 后續EXCEL實戰、常見問題、顏色附錄&#xff0c;持…

計算機網絡面經(一)

以下為個人總結&#xff0c;圖源大部分會來自網絡和JavaGuide 網絡分層模型 OSI七層模型 各層的常見協議 應用層 用戶接口 HTTP, FTP, SMTP, DNS表示層 數據格式轉換 SSL/TLS, JSON, JPEG會話層 會話管理 NetBIOS, RPC, SSH傳輸層 端到端通信 TCP, UDP, QUIC網絡層 路由尋址…

《JVM考古現場(十四):混沌重啟——從量子永生到宇宙熱寂的終極編譯》

開篇&#xff1a;熵火燎原量子遞歸的終極突圍 "當《誅仙劍陣》的時空凍結算法遭遇量子遞歸暴走&#xff0c;當Project Omega的熱寂代碼在JVM的十三維堆內存中坍縮&#xff0c;此刻我們即將撕開歸墟晶壁&#xff0c;直面從玻爾茲曼大腦到馮諾依曼架構的終極對決&#xff0…

【django】2-2 (django配置) 數據庫配置、緩存配置

文章目錄 5 數據庫配置5.1 常用配置項5.2 數據庫配置示例5.3 其它數據庫配置選項 6 緩存6.1 常用配置項6.2 內置的緩存后端6.3 緩存配置示例6.4 緩存中間件的配置 創建django項目后&#xff0c;會自動生成初始的項目文件如下&#xff1a; manage.py # 管理django項目…

【博客】使用GithubAction自動同步obisidian和hexo倉庫

使用Github Action自動同步obisidian和hexo倉庫&#xff0c;避免手動操作。 本文首發于?慕雪的寒舍 1. 煩惱 先來說說慕雪現在的筆記和博客是怎么管理的吧&#xff0c;我正在使用兩套筆記軟件 思源筆記&#xff1a;私密性高一些&#xff0c;不是博客的筆記都在這里面。由于思…

scala簡介和基礎語法

Scala簡介 Scala 是一門多范式&#xff08;multi-paradigm&#xff09;的編程語言&#xff0c;設計初衷是要集成面向對象編程和函數式編程的各種特性。 Scala 運行在 Java 虛擬機上&#xff0c;并兼容現有的 Java 程序。Scala 源代碼被編譯成 Java 字節碼&#xff0c;所以它可…

7.4考研408數據結構B樹與B+樹專題深度解析

考研408數據結構B樹與B+樹專題深度解析 一、B樹(B-Tree) 1.1 定義與性質 定義: B樹是一種平衡多路查找樹,滿足以下條件: 階數:每個結點最多有 m m m個子樹( m ≥

WEB安全--RCE--RCE的危險函數

一、命令執行 1.1、命令執行原理 <?php $cmd $_GET[cmd]; // 直接獲取用戶輸入 system($cmd); // 不安全 ?>#payload: http://example.com/vuln.php?cmdwhoami#結果: www-data 1.2、危險函數 1.2.1、system() 介紹&#xff1a; 執行外部命令&#xff0c;將命令…

Linux C++ 利用 io_uring 技術批量讀取 tun 文件描述符的數據。

以下是參考的實現代碼&#xff0c;IO_URING 操作必須要進行按頁大小對齊&#xff08;僅在O_DIRECT直接I/O下&#xff09;&#xff0c;不能是非對稱的&#xff0c;一般大多數操作系統頁大小為&#xff1a;4KB。 批量讀取、writev 批量簡寫。 static constexpr int MTU ITap::M…

時序數據庫:InfluxDB命令行操作

學習 InfluxDB 的命令行操作至關重要&#xff0c;它不僅是與數據庫直接交互的工具&#xff0c;也是理解 InfluxDB 核心概念的關鍵途徑。通過命令行&#xff0c;用戶可以高效地執行數據庫管理、數據查詢和插入等任務&#xff0c;深入掌握 InfluxQL 的語法及功能。這對于調試、快…

Bootstrap 表格:高效布局與動態交互的實踐指南

Bootstrap 表格:高效布局與動態交互的實踐指南 引言 Bootstrap 是一個流行的前端框架,它為開發者提供了豐富的組件和工具,使得構建響應式、美觀且功能豐富的網頁變得更加簡單。表格是網頁中常見的元素,用于展示數據。Bootstrap 提供了強大的表格組件,可以幫助開發者輕松…

⑥ ACG-系統管理

上網管理行為是指對員工在工作時間內使用公司網絡的行為進行管理和監督。在企業中&#xff0c;系統管理是實施上網管理行為的重要方式之一。系統管理包括以下幾個方面&#xff1a; 1. 訪問控制&#xff1a;通過設置網絡訪問權限&#xff0c;對員工訪問特定網站或使用特定應用程…

【Docker】Dockerfile 優化工具 hadolint

本文內容均來自個人筆記并重新梳理&#xff0c;如有錯誤歡迎指正&#xff01; 如果對您有幫助&#xff0c;煩請點贊、關注、轉發、訂閱專欄&#xff01; 專欄訂閱入口 | 精選文章 | Kubernetes | Docker | Linux | 羊毛資源 | 工具推薦 | 往期精彩文章 【Docker】&#xff08;全…