日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

elasticSearch入门到java操作api一套搞定

發(fā)布時間:2025/3/19 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 elasticSearch入门到java操作api一套搞定 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

寫在前面

一、下載地址

二、solr與es比較

三、安裝elasticsearch

四、安裝可視化界面(hand插件)

使用

五、安裝kibana

六、學(xué)習(xí)es核心概念

七、IK分詞器插件

八、使用ES

九、es的復(fù)雜查詢

十、集成Springboot

十一、京東搜索


寫在前面

ES(ElasticSearch)相信很多小伙伴都聽過它的鼎鼎大名,但是一直不知道其是如何工作的,今天就靠這一篇文章將它徹底入門!

一、下載地址

因為ES及其部分插件,國內(nèi)下載速度比較慢,這里貼出來華為云的下載鏈接,速度剛剛的!

ElasticSearch: https://mirrors.huaweicloud.com/elasticsearch/?C=N&O=D

logstash: https://mirrors.huaweicloud.com/logstash/?C=N&O=D

kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D

elasticsearch-analysis-ik: https://github.com/medcl/elasticsearch-analysis-ik/releases

cerebro: https://github.com/lmenezes/cerebro/releases

head:https://github.com/mobz/elasticsearch-head

二、solr與es比較

1.es基本開箱即用(解壓就可以用!),非常簡單。Solr安裝稍微復(fù)雜一丟丟!

2.Solr利用Zookeeper進(jìn)行分布式管理,而Es自身帶有分布式協(xié)調(diào)管理功能。

3.Solr支持更多格式的數(shù)據(jù),比如JSON、XML、CSV,而Es僅支持json文件格式。

4.Solr官方提供的功能更多,而Elasticsearch本身更注重核心功能,高級功能多有第三方插件提供,例如圖形化界面需要kibana友好支撐。

5.Solr查詢塊,但更新索引時慢(即插入刪除慢),用于電商等查詢多的應(yīng)用;

? ? ES建立索引快(即查詢慢),即實時性查詢塊,用于facebook新浪等搜索;

? ? Solr是傳統(tǒng)搜索應(yīng)用的有力解決方案,但Elasticsearch更適用于新興的實時搜索應(yīng)用。

6.Solr比較成熟,有一個更大,更成熟的用戶、開發(fā)和貢獻(xiàn)者社區(qū),而Elasticsearch相對開發(fā)維護(hù)者較少,更新太快,學(xué)習(xí)使用成本較高。

三、安裝elasticsearch

要求:jdk1.8以上。

1.解壓即可使用。

jvm.options是jvm的配置文件,默認(rèn)內(nèi)存1G。

elasticsearch.yml是es的配置文件,默認(rèn)9200端口,通信端口是9300。

modules是功能模塊。

plugins是第三方插件。

2.啟動。

雙擊bin/elasticsearch.bat

3.輸入網(wǎng)址

http://localhost:9200/

{"name" : "DESKTOP-BA2JN2H","cluster_name" : "elasticsearch","cluster_uuid" : "BJx-AEKcQoacSXfZhpCI5A","version" : {"number" : "7.6.0","build_flavor" : "default","build_type" : "zip","build_hash" : "7f634e9f44834fbc12724506cc1da681b0c3b1e3","build_date" : "2020-02-06T00:09:00.449973Z","build_snapshot" : false,"lucene_version" : "8.4.0","minimum_wire_compatibility_version" : "6.8.0","minimum_index_compatibility_version" : "6.0.0-beta1"},"tagline" : "You Know, for Search" }

四、安裝可視化界面(hand插件)

1.必須安裝node.js。

2.npm安裝

* git clone git://github.com/mobz/elasticsearch-head.git * cd elasticsearch-head * npm install * npm run start * open http://localhost:9100/

3.解決es跨域問題

elasticsearch.yml配置文件

http.cors.enabled: true http.cors.allow-origin: "*"

4.打開http://localhost:9100/

連接http://localhost:9200/

使用

5.初學(xué),就把es當(dāng)做一個數(shù)據(jù)庫。索引就相當(dāng)于一個數(shù)據(jù)庫,文檔就相當(dāng)于數(shù)據(jù)。

? ? 這個hand把它當(dāng)成一個數(shù)據(jù)展示工具,后面所有的查詢可以在kibana做。

五、安裝kibana

kibana版本要和es版本一致!

1.解壓。

2.啟動(也需要安裝node.js)

bin/kibana.bat

3.訪問http://localhost:5601

4.漢化

\kibana-7.6.0-windows-x86_64\x-pack\plugins\translations\translations\下面有漢化文件。

config/kibana.yml下配置:

i18n.locale: "zh-CN"

5.開發(fā)工具

六、學(xué)習(xí)es核心概念

1.elasticsearch是面向文檔的數(shù)據(jù)庫。關(guān)系型數(shù)據(jù)庫和elasticsearch客觀的對比:

Relational?DB(MySQL)

Elasticsearch

數(shù)據(jù)庫(database)

索引(indices)(就和數(shù)據(jù)庫一樣)

表(tables)

類型types(慢慢會被棄用)

行(rows)

文檔documents

字段(columns)

字段fields

? ? elasticsearch(集群)中可以包含多個索引(數(shù)據(jù)庫),每個索引中可以包含多個類型(表),每個類型下又包含多個文檔(行),每個文檔中又包含多個字段(列)。

2.物理設(shè)計

? ? elasticsearch在后臺把每個索引劃分成多個分片,每分分片可以在集群中的不同服務(wù)器間遷移。

? ? 一個人就是一個集群!默認(rèn)的集群名稱就是elasticsearch。

3.邏輯設(shè)計

? ? 一個索引類型中,包含多個文檔,比如說文檔1,文檔2。當(dāng)我們索引一篇文檔時,可以通過這樣的一個順序找到它:索引 ->類型 ->?文檔ID,通過這個組合我們就能索引到某個具體的文檔。注意:ID不必是整數(shù),實際上它是個字符串。

①文檔(就是一條條數(shù)據(jù)):

?? ?之前說 elasticsearch是面向文檔的,那么就意味著索引和搜索數(shù)據(jù)的最小單位是文檔,elasticsearch中,文檔有幾個重要屬性:

? ? (1)自我包含,一篇文檔同時包含字段和對應(yīng)的值,也就是同時包含 key: value!

? ? (2)可以是層次型的,一個文檔中包含自文檔,復(fù)雜的邏輯實體就是這么來的!{就是一個json對象!}

? ? (3)靈活的結(jié)構(gòu),文檔不依賴預(yù)先定義的模式,我們知道關(guān)系型數(shù)據(jù)庫中,要提前定義字段才能使用,在elasticsearch中,對于字段是非常靈活的,有時候,我們可以忽略該字段,或者動態(tài)的添加一個新的字段。? ?

?? ?盡管我們可以隨意的新増或者忽略某個字段,但是,每個字段的類型非常重要,比如一個年齡字段類型,可以是字符串也可以是整形。因為 elasticsearch會保存字段和類型之間的映射及其他的設(shè)置。這種映射具體到毎個映射的每種類型,這也是為什么在elasticsearch中,類型有時候也稱為映射類型。

②類型(較少去用了)

? ? 類型是文檔的邏輯容器,就像關(guān)系型數(shù)據(jù)庫一樣,表格是行的容器。類型中對于字段的定義稱為映射,比如name映射為字符串類型。我們說文檔是無模式的,它們不需要擁有映射中所定義的所有字段,比如新增一個字段,那么 elasticsearch是怎么做的呢?elasticsearch會自動的將新字段加入映射,但是這個字段的不確定它是什么類型, elasticsearch就開始猜,如果這個值是18,那么elasticsearch會認(rèn)為它是整形。但是 elastirsearch也可能猜不對,所以最安全的方式就是提前定義好所需要的映射,這點(diǎn)跟關(guān)系型數(shù)據(jù)庫殊途同歸了,先定義好字段,然后再使用,別整什么幺蛾子。

③索引

?? ?索引就是數(shù)據(jù)庫!

?? ?索引是映射類型的容器, elasticsearch中的索引是一個非常大的文檔集合。索引存儲了映射類型的字段和其他設(shè)置。然后它們被存儲到了各個分片上了。我們來研究下分片是如何工作的。

4.物理設(shè)計:節(jié)點(diǎn)和分片如何工作

? ? 一個集群至少有一個節(jié)點(diǎn),,而一個節(jié)點(diǎn)就是一個 elasticsearch進(jìn)程,節(jié)點(diǎn)可以有多個索引默認(rèn)的,如果你創(chuàng)建索引,那么索引將會有個5個分片( primary shard,又稱主分片)構(gòu)成的,每一個主分片會有一個副本( replica shard,又稱復(fù)制分片)

?? ?上圖是一個有3個節(jié)點(diǎn)的集群,可以看到主分片和對應(yīng)的復(fù)制分片都不會在同一個節(jié)點(diǎn)內(nèi),這樣有利于某個節(jié)點(diǎn)掛掉了,數(shù)據(jù)也不至于丟失。實際上,一個分片是一個 Lucene索引,一個包含倒排索引圖的文件目錄,倒排索引的結(jié)構(gòu)使得 elasticsearch在不掃描全部文檔的情況下,就能告訴你哪些文檔包含特定的關(guān)鍵字。不過,等等,倒排索引是什么鬼?

5.倒排索引

?? ?elasticsearch使用的是一種稱為倒排索引的結(jié)構(gòu),采用 Lucene倒排索作為底層。這種結(jié)構(gòu)適用于快速的全文搜索,一個索引由文檔中所有不重復(fù)的列表構(gòu)成,對于每一個詞,都有一個包含它的文檔列表。例如,現(xiàn)在有兩個文檔,每個文檔包含如下內(nèi)容:

?? ?為了創(chuàng)建倒排索引,我們首先要將每個文檔拆分成獨(dú)立的詞(或稱為詞條或者 tokens),然后創(chuàng)建一個包含所有不重復(fù)的詞條的排序列表,然后列出每個詞條出現(xiàn)在哪個文檔。

? ? 現(xiàn)在我們試圖搜索to?forever,只需要查看包含每個詞條的文檔。

?? ?兩個文檔都匹配,但是第一個文檔比第二個匹配程度更高。如果沒有別的條件,現(xiàn)在,這兩個包含關(guān)鍵字的文檔都將返回。

?? ?再來看一個示例,比如我們通過博客標(biāo)簽來搜索博客文章。那么倒排索引列表就是這樣的一個結(jié)構(gòu):

?? ?如果要搜索含有 python標(biāo)簽的文章,那相對于査找所有原始數(shù)據(jù)而言,査找倒排索引后的數(shù)據(jù)將會快的多。只需要査看標(biāo)簽這欄,然后獲取相關(guān)的文章ID即可。完全過濾掉無關(guān)的所有數(shù)據(jù),提高效率!

?? ?elasticsearch的索引和 Lucene的索引對比:

?? ?在 elasticsearch中,索引這個詞被頻繁使用,這就是術(shù)語的使用。在 elasticsearch中,索引被分為多個分片,每份分片是一個Lucene的索引。所以一個 elasticsearch索引是由多個 Lucene索引組成的。別問為什么,誰讓 elasticsearchy使用 Lucene作為底層呢!如無特指,說起索引都是指 elasticsearch的索引。

七、IK分詞器插件

1.什么是IK分詞器

?? ?分詞:即把一段中文或者別的劃分成一個個的關(guān)鍵字,我們在搜索時候會把自己的信息進(jìn)行分詞,會把數(shù)據(jù)庫中或者索引庫中的數(shù)據(jù)進(jìn)行分詞,然后進(jìn)行—個匹配操作,默認(rèn)的中文分詞是將毎個字看成一個詞,比如“我愛狂神”會被分為"我""愛""狂"神",這顯然是不符合要求的,所以我們需要安裝中文分詞器IK來解決這個問題。

? ? 如果要使用中文,建議使用IK分詞器!

? ? IK提供了兩個分詞算法: ik_smart和 ik_max_word,其中 ik_smart為最少切分,ik_max_word為最細(xì)粒度劃分!

2.下載安裝(下載與es對應(yīng)的版本!!!否則會啟動報錯)

①下載完,解壓到ES目錄下

D:\es\elasticsearch-7.6.0\plugins\elasticsearch-analysis-ik-7.6.0

②重啟es,會出現(xiàn)加載ik插件

[2021-05-07T09:51:29,253][INFO ][o.e.p.PluginsService ] [DESKTOP-KAO1R1F] loaded plugin [analysis-ik]

③使用elasticsearch-plugin.bat,查看插件

3.使用kibana測試

GET _analyze {"analyzer" : "ik_smart","text" : "中國共產(chǎn)黨" }{"tokens" : [{"token" : "中國共產(chǎn)黨","start_offset" : 0,"end_offset" : 5,"type" : "CN_WORD","position" : 0}] } GET _analyze {"analyzer" : "ik_max_word","text" : "中國共產(chǎn)黨" }{"tokens" : [{"token" : "中國共產(chǎn)黨","start_offset" : 0,"end_offset" : 5,"type" : "CN_WORD","position" : 0},{"token" : "中國","start_offset" : 0,"end_offset" : 2,"type" : "CN_WORD","position" : 1},{"token" : "國共","start_offset" : 1,"end_offset" : 3,"type" : "CN_WORD","position" : 2},{"token" : "共產(chǎn)黨","start_offset" : 2,"end_offset" : 5,"type" : "CN_WORD","position" : 3},{"token" : "共產(chǎn)","start_offset" : 2,"end_offset" : 4,"type" : "CN_WORD","position" : 4},{"token" : "黨","start_offset" : 4,"end_offset" : 5,"type" : "CN_CHAR","position" : 5}] }

②有些詞被拆分了,需要自己來配置分詞

重啟es看細(xì)節(jié)

[2021-05-07T10:21:48,875][INFO ][o.e.g.GatewayService ] [DESKTOP-KAO1R1F] recovered [5] indices into cluster_state [2021-05-07T10:21:49,223][INFO ][o.w.a.d.Monitor ] [DESKTOP-KAO1R1F] try load config from D:\es\elasticsearch-7.6.0\config\analysis-ik\IKAnalyzer.cfg.xml [2021-05-07T10:21:49,228][INFO ][o.w.a.d.Monitor ] [DESKTOP-KAO1R1F] try load config from D:\es\elasticsearch-7.6.0\plugins\elasticsearch-analysis-ik-7.6.0\config\IKAnalyzer.cfg.xml [2021-05-07T10:21:49,751][INFO ][o.w.a.d.Monitor ] [DESKTOP-KAO1R1F] [Dict Loading] D:\es\elasticsearch-7.6.0\plugins\elasticsearch-analysis-ik-7.6.0\config\cxf.dic

八、使用ES

1.基本REST

2.基礎(chǔ)索引測試

①創(chuàng)建索引

格式: PUT /索引名/(類型名,以后可能不會用到了)/文檔id {請求體}示例: PUT /test1/type1/1 {"name" : "永遠(yuǎn)的神","age" : 3 }#! Deprecation: [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}). {"_index" : "test1","_type" : "type1","_id" : "1","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1 }

? ? 完成了自動增加了索引!數(shù)據(jù)也添加成功了!索引初期可以當(dāng)做一個數(shù)據(jù)庫!

②指定字段的類型

text類型會被分詞解析,keyword是不會被分詞解析的!

創(chuàng)建規(guī)則: PUT /test2 {"mappings": {"properties": {"name" : {"type" :"text"},"age" : {"type" : "long"},"birthday" : {"type" : "date"}}} }

③獲得數(shù)據(jù)信息

GET /test2

④查看默認(rèn)的信息

如果沒有指定字段類型,那么es會自動設(shè)置默認(rèn)的字段類型

PUT /test3/_doc/1 {"name" : "張三","age" : 18 }使用GET: GET /test3 結(jié)果: {"test3" : {"aliases" : { },"mappings" : {"properties" : {"age" : {"type" : "long"},"name" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}},"settings" : {"index" : {"creation_date" : "1620355778195","number_of_shards" : "1","number_of_replicas" : "1","uuid" : "b4ATwfKGQ9yoNgB2ce-UOA","version" : {"created" : "7060099"},"provided_name" : "test3"}}} } 獲取健康狀態(tài) GET _cat/health1620356456 03:00:56 elasticsearch yellow 1 1 12 12 0 0 8 0 - 60.0%查看信息 GET _cat/indices?vhealth status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open test2 n1Yl5LvZSlyGrsirb3JyrQ 1 1 0 0 283b 283b yellow open test3 b4ATwfKGQ9yoNgB2ce-UOA 1 1 1 0 3.7kb 3.7kb green open .kibana_task_manager_1 uwnOx-ktSl-kLenHmgyQhg 1 0 2 0 13kb 13kb green open .apm-agent-configuration ESfhRweTTxOjx_5NFH0V7Q 1 0 0 0 283b 283b green open kibana_sample_data_flights RXgt4tWjQNqbAMEZnleV3g 1 0 13059 0 6.2mb 6.2mb green open .kibana_1 w_wKw0LxQEitRAWALeQSng 1 0 80 3 136.9kb 136.9kb yellow open test1 SCHGcDpZRYGvTGhhXjqaEg 1 1 1 0 3.7kb 3.7kb yellow open db r1AqWtE1Q_i2I4kwcpMvZQ 5 1 0 0 1.3kb 1.3kb

⑤修改

1.直接覆蓋: PUT /test3/_doc/1 {"name" : "李四","age" : 18 }修改之后版本號會+12.使用POST修改 POST /test3/_doc/1/_update {"doc" : {"name" : "王五"} }

⑥刪除

DELETE /test3/_doc/1DELETE /test3

3.關(guān)于文檔的操作

①添加數(shù)據(jù):

PUT /cxf/user/1 {"name" : "張三","age" : 24,"desc" : "永遠(yuǎn)的神","tags" : ["強(qiáng)", "溫暖", "博愛"] }PUT /cxf/user/2 {"name" : "張四","age" : 25,"desc" : "永遠(yuǎn)的2","tags" : ["旅游", "玩游戲", "渣男"] }PUT /cxf/user/3 {"name" : "張五","age" : 22,"desc" : "永遠(yuǎn)的5","tags" : ["玩", "逛街", "帥b"] }

②獲取數(shù)據(jù):

GET /cxf/user/3

③更新數(shù)據(jù):

PUT是完全覆蓋,POST修改是修改指定的屬性

PUT /cxf/user/3 {"name" : "張四2","age" : 25,"desc" : "永遠(yuǎn)的2","tags" : ["旅游", "玩游戲", "渣男"] }POST /cxf/user/3/_update {"doc" : {"name" : "張四4"} }

九、es的復(fù)雜查詢

查詢出來的東西:

hits:索引和文檔的信息。

total:查詢結(jié)果總數(shù)。

然后就是查詢出來的具體文檔。

數(shù)據(jù)中的東西都可以遍歷出來了。

分?jǐn)?shù):我們可以通過來判斷誰更加符合結(jié)果。

#! Deprecation: [types removal] Specifying types in search requests is deprecated. {"took" : 2,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 0.6409958,"hits" : [{"_index" : "cxf","_type" : "user","_id" : "2","_score" : 0.6409958,"_source" : {"name" : "張四","age" : 25,"desc" : "永遠(yuǎn)的2","tags" : ["旅游","玩游戲","渣男"]}},{"_index" : "cxf","_type" : "user","_id" : "3","_score" : 0.5403744,"_source" : {"name" : "張四4","age" : 25,"desc" : "永遠(yuǎn)的2","tags" : ["旅游","玩游戲","渣男"]}},{"_index" : "cxf","_type" : "user","_id" : "1","_score" : 0.14181954,"_source" : {"name" : "張三","age" : 24,"desc" : "永遠(yuǎn)的神","tags" : ["強(qiáng)","溫暖","博愛"]}}]} } 1.通過id查詢: GET /cxf/user/3 2.條件查詢: GET /cxf/user/_search?q=name:張三3.query查詢: GET /cxf/user/_search {"query": {"match": {"name": "張四" // 匹配屬性值}},"_source" : ["name", "age"] // 結(jié)果過濾, "sort": [ // 排序,排序之后分值就為null了{(lán)"age": {"order": "desc"}}],"from": 0, // 分頁,相當(dāng)于limit。from是從第幾條開始,size是每頁多少條數(shù)據(jù)"size": 2 }4.多條件精確查詢: GET /cxf/user/_search {"query": {"bool": {"must": [ // 相當(dāng)于mysql的and,所有的條件都要符合{"match": {"name": "張三"}},{"match": {"age": 24}}]}} }5.or操作: GET /cxf/user/_search {"query": {"bool": {"should": [ // 等價于or{"match": {"name": "張三"}},{"match": {"age": 25}}]}} }6.查詢不是 GET /cxf/user/_search {"query": {"bool": {"must_not": [ // 等價于!={"match": {"name": "三"}},{"match": {"age": 24}}]}} }7.過濾條件 GET /cxf/user/_search {"query": {"bool": {"must": [{"match": {"name": "張三"}}],"filter": {"range": {"age": {"gte": 10, // 查詢條件"lte": 24}}}}} } gt:大于 gte:大于等于 lt:小于 lte:小于等于8.匹配多個條件 多條件用空格隔開,只要滿足其中一個結(jié)果既可以被查出,這個時候可以通過分值進(jìn)行判斷。 GET /cxf/user/_search {"query": {"match": {"tags": "男 游戲"}} }9.精確查詢 term查詢是直接通過倒排查詢進(jìn)行精確查詢的。 term是直接查詢精確的值。 match會使用分詞器。(先分析文檔,然后再通過分析的文檔進(jìn)行查詢!) text類型會被分詞解析,keyword是不會被分詞解析的! GET /cxf/user/_search {"query": {"term": {"name": {"value": "張四"}}} }10.高亮查詢 GET /cxf/user/_search {"query": {"match": {"name": "張三"}},"highlight": { // 搜索的高亮條件,會自動增加<em>張</em>標(biāo)簽"pre_tags": "<p class='key' style='color:red'>", // 自定義高亮標(biāo)簽"post_tags": "</p>","fields": {"name":{}}} }

十、集成Springboot

1.pom

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.6.0</version> </dependency>properties中需要指定es版本: <elasticsearch.version>7.6.0</elasticsearch.version><!--elasticsearch--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>

2.配置

import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class ElasticsearchConfig {@Beanpublic RestHighLevelClient restHighLevelClient(){RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));return restHighLevelClient;} }

3.具體api

import com.alibaba.fastjson.JSON; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.CreateIndexResponse; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.TimeUnit;@RequestMapping("/es") @Controller public class ElasticsearchController {@Autowired@Qualifier("restHighLevelClient")private RestHighLevelClient client;/*** 索引*/@RequestMapping("/test1")public void test1() throws IOException {// 創(chuàng)建索引CreateIndexRequest indexCui = new CreateIndexRequest("cui");CreateIndexResponse resp = client.indices().create(indexCui, RequestOptions.DEFAULT);System.out.println(resp);// 判斷索引是否存在GetIndexRequest getIndexRequest = new GetIndexRequest("cui");boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);System.out.println(exists);//刪除索引DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("cui");AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);System.out.println(delete);}/*** POST添加數(shù)據(jù)*/@RequestMapping("/test2")public void test2() throws IOException {EsUser esUser = new EsUser();esUser.age =18;esUser.name = "張三";// 連接索引IndexRequest cui = new IndexRequest("cui");//規(guī)則 /cui/_doc/1cui.id("1");cui.timeout(TimeValue.timeValueSeconds(10));//cui.timeout("10s");// 請求體放進(jìn)去cui.source(JSON.toJSONString(esUser), XContentType.JSON);//客戶端發(fā)送請求IndexResponse index = client.index(cui, RequestOptions.DEFAULT);System.out.println(index);// 第一次是created,以后再添加就是update了}/*** 文檔操作*/@RequestMapping("/test3")public void test3() throws IOException {/*** 判斷文檔是否存在*/GetRequest cui = new GetRequest("cui", "1");//不獲取返回的上下文(_source)cui.fetchSourceContext(new FetchSourceContext(false));cui.storedFields("_none_");boolean exists = client.exists(cui, RequestOptions.DEFAULT);System.out.println(exists);GetRequest idx = new GetRequest("cui", "1");GetResponse documentFields = client.get(idx, RequestOptions.DEFAULT);System.out.println(documentFields.getSourceAsString());// 打印文檔內(nèi)容System.out.println(documentFields); // 返回的全部內(nèi)容和命令是一樣的/*** 更新*/EsUser esUser = new EsUser();esUser.age =19;esUser.name = "張四";UpdateRequest cui1 = new UpdateRequest("cui", "1");cui1.timeout("1s");cui1.doc(JSON.toJSONString(esUser), XContentType.JSON);UpdateResponse update = client.update(cui1, RequestOptions.DEFAULT);System.out.println(update);/*** 刪除*/DeleteRequest cui2 = new DeleteRequest("cui", "1");cui2.timeout("1s");DeleteResponse delete = client.delete(cui2, RequestOptions.DEFAULT);System.out.println(delete);}/*** 批量操作*/@RequestMapping("/test4")public void test4() throws IOException {BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");ArrayList<EsUser> list = new ArrayList<>();list.add(new EsUser("崔1", 21));list.add(new EsUser("崔2", 22));list.add(new EsUser("崔3", 23));list.add(new EsUser("崔4", 24));list.add(new EsUser("崔5", 25));list.add(new EsUser("崔6", 26));list.add(new EsUser("崔7", 27));//批處理for (int i = 0; i < list.size(); i++) {// 批量修改刪除,對應(yīng)修改即可bulkRequest.add(new IndexRequest("cui").id(i + 1 + "") // 不寫id會隨機(jī)生成id.source(JSON.toJSONString(list.get(i)), XContentType.JSON));}BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk);}/*** 查詢* 就是對應(yīng)基本的所有命令*/@RequestMapping("/test5")public void test5() throws IOException {SearchRequest searchRequest = new SearchRequest("cui");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//使用QueryBuilders,快速匹配查詢條件MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "崔1");searchSourceBuilder.query(matchQueryBuilder).from(0)// 分頁.size(10).timeout(new TimeValue(10, TimeUnit.SECONDS));//searchSourceBuilder.highlighter();// 高亮searchRequest.source(searchSourceBuilder);// 把查詢條件放到searchRequestSearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);System.out.println(search.getHits());// 文檔內(nèi)容System.out.println(search);for (SearchHit documentFields : search.getHits().getHits()) {System.out.println(documentFields.getSourceAsMap());// 遍歷}}}class EsUser{public String name;public Integer age;public EsUser(String name, Integer age) {this.name = name;this.age = age;}public EsUser() {} }

十一、京東搜索

1.導(dǎo)入包

<!--解析網(wǎng)頁 jsoup ; tika包是解析視頻音樂的--> <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.10.2</version> </dependency>

2.代碼

import org.jsoup.Connection; import org.jsoup.helper.HttpConnection; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements;import java.io.IOException; import java.net.URL; import java.util.ArrayList;public class HtmlParseUtils {public static void main(String[] args) throws IOException {ArrayList<Info> java = HtmlParseUtils.getInfo("java");for (Info info : java) {System.out.println(info);}}public static ArrayList<Info> getInfo(String info) throws IOException {// 獲取請求String url = "https://search.jd.com/Search?keyword=" + info;//解析網(wǎng)頁(解析返回的document就是瀏覽器的document對象)URL u = new URL(url);Connection con = HttpConnection.connect(url);con.timeout(300000);con.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3861.400 QQBrowser/10.7.4313.400");con.header("cookie", "unpl=V2_ZzNtbURREEF3XxZReBAPVWIBRllKBUEQcw0VAyxOWVJhCkcIclRCFnUUR1BnGFUUZgoZWUNcQhFFCEdkeBBVAWMDE1VGZxBFLV0CFSNGF1wjU00zQwBBQHcJFF0uSgwDYgcaDhFTQEJ2XBVQL0oMDDdRFAhyZ0AVRQhHZH8ZXQBmBxteRmdzEkU4dl1yEV4DZTMTbUNnAUEpC0dSchtZSGMDE1hDU0oWcThHZHg%3d; __jdv=76161171|baidu-pinzhuan|t_288551095_baidupinzhuan|cpc|0f3d30c8dba7459bb52f2eb5eba8ac7d_0_77be3fa428ba43e59c3474bfff4f78dd|1620435006518; __jdu=510405825; areaId=13; ipLoc-djd=13-1007-37918-0; PCSYCityID=CN_370000_370200_370212; shshshfpa=b63cfa52-dd75-9d21-c820-0ae5f6a96ef1-1620435009; shshshfpb=abapWi%2F0i4o6AgQnM%2F5q%2F%2FQ%3D%3D; __jda=122270672.510405825.1620435006.1620435006.1620435007.1; __jdc=122270672; shshshfp=11c5062f56e8e6ad00ad498a9d3ab294; rkv=1.0; wlfstk_smdl=iycergr2qqxobmcam67n8ptxywbmufhd; qrsc=3; __jdb=122270672.8.510405825|1.1620435007; shshshsID=6e200de4a4e9605b03810b2ab647eb98_6_1620437334053; 3AB9D23F7A4B3C9B=RMWCKZRXMVHOY7FERSQDF7FV25CGZRNEEBLRZZLDHQWLBCLNY3I57D76RTH27WDER2KFJOAIHWKZJH7YDX7KREP5VA");Document document = con.get();//Document document = Jsoup.parse(u, 300000); // 京東這里會跳轉(zhuǎn)到登錄,咱們加上cookie// 所有js中能使用的方法,這里都能用Element j_goodsList = document.getElementById("J_goodsList");//獲取所有l(wèi)i標(biāo)簽Elements li = j_goodsList.getElementsByTag("li");ArrayList<Info> list = new ArrayList<>();for (Element element : li) {String img = element.getElementsByTag("img").eq(0).attr("data-lazy-img");String price = element.getElementsByClass("p-price").eq(0).text();String name = element.getElementsByClass("p-name").eq(0).text();Info infos = new Info();infos.img = img;infos.name = name;infos.price = price;list.add(infos);}return list;} }class Info{String img;String price;String name;public String getImg() {return img;}public void setImg(String img) {this.img = img;}public String getPrice() {return price;}public void setPrice(String price) {this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Info{" +"img='" + img + '\'' +", price='" + price + '\'' +", name='" + name + '\'' +'}';} } import com.alibaba.fastjson.JSON; import org.apache.http.HttpHost; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit;public class EsTest {private static RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));public static void main(String[] args) throws IOException {// insert();// 入庫// 查詢List<Map<String, Object>> java = searchPage("java", 0, 10);if(java.size() == 0){System.out.println("無數(shù)據(jù)");return;}for (Map<String, Object> stringObjectMap : java) {System.out.println(stringObjectMap);}}/*** 批量入庫* @throws IOException*/public static void insert() throws IOException {// 批量添加ArrayList<Info> list = HtmlParseUtils.getInfo("大數(shù)據(jù)");BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");//批處理for (int i = 0; i < list.size(); i++) {// 批量修改刪除,對應(yīng)修改即可bulkRequest.add(new IndexRequest("jingdong")//.id(i + 1 + "") // 不寫id會隨機(jī)生成id.source(JSON.toJSONString(list.get(i)), XContentType.JSON));}BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk);}public static List<Map<String, Object>> searchPage(String key, int pageNo, int pageSize) throws IOException {if(pageNo < 0){pageNo = 0;}SearchRequest searchRequest = new SearchRequest("jingdong");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//使用QueryBuilders,快速匹配查詢條件MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", key);searchSourceBuilder.query(matchQueryBuilder).from(pageNo)// 分頁.size(pageSize).timeout(new TimeValue(10, TimeUnit.SECONDS));//searchSourceBuilder.highlighter();// 高亮//高亮HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("name").requireFieldMatch(false) //多個高亮顯示.preTags("<span style='color:red'>").postTags("</span>");searchSourceBuilder.highlighter(highlightBuilder);searchRequest.source(searchSourceBuilder);// 把查詢條件放到searchRequestSearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);//System.out.println(search.getHits());// 文檔內(nèi)容//System.out.println(search);List<Map<String, Object>> list = new ArrayList<>();for (SearchHit documentFields : search.getHits().getHits()) {//System.out.println(documentFields.getSourceAsMap());// 遍歷Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();// 原來的HighlightField name = documentFields.getHighlightFields().get("name"); // 獲取name高亮if(name != null){//替換高亮字段Text[] fragments = name.fragments();String newName = "";for (Text fragment : fragments) {newName += fragment;}sourceAsMap.put("name", newName);// 替換原來的name// 高亮之后,使用v-html解析即可}list.add(sourceAsMap);}return list;}}

總結(jié)

以上是生活随笔為你收集整理的elasticSearch入门到java操作api一套搞定的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。