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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

用于Elasticsearch成绩单的Java客户端

發布時間:2023/12/3 java 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用于Elasticsearch成绩单的Java客户端 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在本演講中,我將介紹用于Elasticsearch和Spring Data Elasticsearch的三個不同的客戶端。 首先,讓我們看一下Elasticsearch的一些基礎知識。

彈性搜索

為了介紹elasticsearch,我使用的定義直接來自Elastic網站。

Elasticsearch是基于JSON的分布式搜索和分析引擎,旨在實現水平可伸縮性,最大的可靠性和易于管理的功能。

首先讓我們看看基于JSON的搜索和分析引擎的含義。

要了解elasticsearch的功能,最好查看搜索頁面的示例。 這是每個人都熟悉的,在Github上進行代碼搜索。

可以在單個搜索輸入中輸入關鍵字,下面是結果列表。 搜索引擎和其他數據庫之間的顯著特征之一是存在相關性的概念。 我們可以看到,對于我們的搜索詞elasticsearch來說,搜索引擎的項目是第一位的。 人們在搜索該術語時很可能正在尋找項目。 用來確定結果是否比另一個結果更相關的因素可能因應用程序而異-我不知道Github在做什么,但是我可以想象除了經典的文本相關性功能之外,他們還在使用諸如流行度之類的因素。 像elasitcsearch這樣的經典搜索引擎支持的網站上還有更多功能:突出顯示結果中的出現,對列表進行分頁并使用不同的條件進行排序。 在左側,您可以看到所謂的構面,這些構面可用于根據找到的文檔中的條件進一步細化結果列表。 這類似于在ebay和Amazon等電子商務網站上發現的功能。 為此,elasticsearch具有聚合功能,這也是其分析功能的基礎。 使用彈性搜索也可以做到這一點。 在這種情況下,這一點更加明顯– Github實際上是在使用Elasticsearch來搜索存儲的大量數據。

如果要構建這樣的搜索應用程序,則必須先安裝引擎。 幸運的是,elasticsearch非常容易上手。 除了最近的Java運行時之外,沒有其他特殊要求。 您可以從elastic網站上下載elasticsearch檔案,將其解壓縮并使用腳本啟動elasticsearch。

# download archive wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.0.0.zipunzip elasticsearch-5.0.0.zip# on windows: elasticsearch.bat elasticsearch-5.0.0/bin/elasticsearch

對于生產用途,還有用于不同Linux發行版的軟件包。 您可以看到通過在標準端口上執行HTTP GET請求來啟動elasticsearch。 在示例中,我使用的是curl,它是用于執行HTTP請求的命令行客戶端,可用于許多環境。

curl -XGET "http://localhost:9200"

elasticsearch將使用包含有關安裝信息的JSON文檔回答此請求。

{"name" : "LI8ZN-t","cluster_name" : "elasticsearch","cluster_uuid" : "UvbMAoJ8TieUqugCGw7Xrw","version" : {"number" : "5.0.0","build_hash" : "253032b","build_date" : "2016-10-26T04:37:51.531Z","build_snapshot" : false,"lucene_version" : "6.2.0"},"tagline" : "You Know, for Search" }

對我們來說,最重要的事實是我們可以看到服務器已啟動。 但是,還有關于Elasticsearch和Lucene的版本信息,Lucene是用于大多數搜索功能的基礎庫。

如果現在我們想將數據存儲在elasticsearch中,我們也將其作為JSON文檔發送,這次使用POST請求。 因為我非常喜歡新加坡的食物,所以我想構建一個應用程序,讓我可以搜索自己喜歡的食物。 讓我們索引第一道菜。

curl -XPOST "http://localhost:9200/food/dish" -d' {"food": "Hainanese Chicken Rice","tags": ["chicken", "rice"],"favorite": {"location": "Tian Tian","price": 5.00} }'

我們使用的端口與之前使用的端口相同,這次我們僅向URL添加兩個片段: food和dish 。 第一個是索引的名稱,即文件的邏輯集合。 第二種是類型。 它確定了我們要保存的文檔的結構,即所謂的映射。

盤子本身被建模為文檔。 elasticsearch支持不同的數據類型,如字符串,用于food的屬性,就像在一個列表tags和喜歡的,甚至嵌入文檔favorite文件。 除此之外,還有更多原始類型,例如數字,布爾值和特殊類型,例如地理坐標。

現在我們可以索引另一個執行另一個POST請求的文檔。

curl -XPOST "http://localhost:9200/food/dish" -d' {"food": "Ayam Penyet","tags": ["chicken", "indonesian"],"spicy": true }'

本文檔的結構有些不同。 它不包含“ favorite子文檔,但具有另一個“ spicy屬性。 相同類型的文檔可能會非常不同–但是請記住,您需要解釋應用程序中的某些部分。 通常,您將擁有類似的文件。

將這些文檔編入索引,就可以自動搜索它們。 一種選擇是在/_search上執行GET請求,并將查詢項添加為參數。

curl -XGET "http://localhost:9200/food/dish/_search?q=chicken"

在兩個文檔中搜索雞肉也將同時返回它們。 這是結果的摘錄。

... {"total":2,"max_score":0.3666863,"hits":[{"_index":"food","_type":"dish","_id":"AVg9cMwARrBlrY9tYBqX","_score":0.3666863,"_source": {"food": "Hainanese Chicken Rice","tags": ["chicken", "rice"],"favorite": {"location": "Tian Tian","price": 5.00} }}, ...

有一些全局信息,例如找到的文檔數量。 但最重要的屬性是hits數組,其中包含我們索引盤的原始來源。

這樣很容易上手,但是大多數情況下查詢會更復雜。 這就是為什么Elasticsearch提供查詢DSL(一種描述查詢以及請求的任何其他搜索功能的JSON結構)的原因。

curl -XPOST "http://localhost:9200/food/dish/_search" -d' {"query": {"bool": {"must": {"match": {"_all": "rice"}},"filter": {"term": {"tags.keyword": "chicken"}}}} }'

我們正在搜索所有包含術語rice并且在tags也包含chicken文檔。 使用.keyword訪問字段允許進行精確搜索,并且是.keyword 5.0中的新功能。

除了搜索本身之外,您還可以使用查詢DSL向Elasticsearch請求更多信息,例如高亮顯示或自動補全或可用于構建構面功能的聚合。

讓我們繼續定義的另一部分。

Elasticsearch是[…]分布式[…],旨在實現水平可伸縮性,最大的可靠性

到目前為止,我們僅訪問了一個Elasticsearch實例。

我們的應用程序將直接與該節點通信。 現在,由于Elasticsearch是為水平可伸縮性設計的,因此我們還可以添加更多節點。

節點形成集群。 我們仍然可以與第一個節點通信,它將所有請求分發到集群的必要節點。 這對我們完全透明。

從一開始就使用Elasticsearch構建集群真的很容易,但是維護生產集群當然會更具挑戰性。

現在,我們對Elasticsearch的功能有了基本的了解,讓我們看看如何從Java應用程序訪問它。

運輸客戶

傳輸客戶端從一開始就可用,并且是最經常選擇的客戶端。 從elasticsearch 5.0開始,它具有自己的工件,可以將其集成到您的構建中,例如使用Gradle。

dependencies {compile group: 'org.elasticsearch.client',name: 'transport',version: '5.0.0' }

Elasticsearch的所有功能都可以通過Client接口使用,一個具體的實例是TransportClient ,可以使用Settings對象來實例化它,并且可以具有一個或多個Elasticsearch節點地址。

TransportAddress address =new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300);Client client = new PreBuiltTransportClient(Settings.EMPTY)addTransportAddress(address);

然后, client為彈性搜索的不同功能提供方法。 首先,讓我們再次搜索。 回想一下我們上面發布的查詢的結構。

curl -XPOST "http://localhost:9200/food/dish/_search" -d' {"query": {"bool": {"must": {"match": {"_all": "rice"}},"filter": {"term": {"tags.keyword": "chicken"}}}} }'

一個bool查詢,在其must區域中具有match查詢,而在filter區域中具有term查詢。

幸運的是,一旦有了這樣的查詢,就可以輕松地將其轉換為Java等效項。

SearchResponse searchResponse = client.prepareSearch("food").setQuery(boolQuery().must(matchQuery("_all", "rice")).filter(termQuery("tags.keyword", "chicken"))).execute().actionGet();assertEquals(1, searchResponse.getHits().getTotalHits());SearchHit hit = searchResponse.getHits().getAt(0); String food = hit.getSource().get("food").toString();

我們通過在client上調用prepareSearch來請求SearchSourceBuilder 。 在這里,我們可以使用靜態幫助器方法設置查詢。 再說一次,這是一個bool查詢,在must區域有一個match查詢,而在filter區域有一個term查詢。

調用execute返回一個Future對象, actionGet是調用的阻塞部分。 SearchResponse表示使用HTTP接口進行搜索時可以看到的相同JSON結構。 然后,菜的來源可作為地圖使用。

索引數據時,有不同的選項可用。 一種是使用jsonBuilder創建JSON表示形式。

XContentBuilder builder = jsonBuilder().startObject().field("food", "Roti Prata").array("tags", new String [] {"curry"}).startObject("favorite").field("location", "Tiong Bahru").field("price", 2.00).endObject().endObject();

它提供了可用于創建JSON文檔結構的不同方法。 然后可以將其用作IndexRequest的源。

IndexResponse resp = client.prepareIndex("food","dish").setSource(builder).execute().actionGet();

除了使用jsonBuilder還有其他幾個可用選項。

常見的選擇是使用Map(一種接受字段名稱和值以獲取簡單結構的便捷方法)或使用傳遞String的選項(通常與Jackson之類的庫結合使用以進行序列化)。

上面我們已經看到,傳輸客戶端接受一個或多個Elasticsearch節點的地址。 您可能已經注意到,該端口不同于用于http的端口,即9300而不是9200。這是因為客戶端不通過http進行通信–它使用傳輸協議連接到現有集群,該二進制協議也是用于集群中的節點間通信。

您可能還已經注意到,到目前為止,我們僅在與集群的一個節點通信。 一旦該節點發生故障,我們可能將無法再訪問我們的數據。 如果您需要高可用性,則可以啟用嗅探選項,該選項可使您的客戶端與群集中的多個節點通信。

現在,當其中一個節點發生故障時,我們仍然可以使用其他節點訪問數據。 創建客戶端時,可以通過將client.transport.sniff設置為true來啟用該功能。

TransportAddress address =new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300);Settings settings = Settings.builder().put("client.transport.sniff", true).build();Client client = new PreBuiltTransportClient(settings)addTransportAddress(address);

此功能通過使用elasticsearch的管理API之一從已知節點請求集群的當前狀態來起作用。 配置后,此操作將在啟動過程中以固定的間隔完成,默認情況下每5s進行一次。

嗅探是一項重要功能,即使在節點發生故障時,也可以確保您的應用程序保持正常運行。

使用傳輸客戶端時,您會看到一些明顯的好處:隨著客戶端隨服務器一起提供(甚至包括對服務器的依賴關系),您可以確保所有當前API都可以在客戶端代碼中使用。 通信比HTTP上的JSON更有效,并且支持客戶端負載平衡。

另一方面,也存在一些缺點:由于傳輸協議是內部協議,因此您需要在服務器和客戶端上使用兼容的Elasticsearch版本。 同樣,這出乎意料之外,這還意味著需要使用類似的JDK版本。 另外,您需要在應用程序中包括所有對Elasticsearch的依賴項。 這可能是一個巨大的問題,尤其是對于較大的現有應用程序。 例如,CMS可能已經發行了某些版本的Lucene。 通常,不可能像這樣解決依賴沖突。

幸運的是,有一個解決方案。

RestClient

elasticsearch 5.0引入了一個新客戶端,該客戶端使用elasticsearch的HTTP API而不是內部協議。 這需要更少的依賴性。 同樣,您也不需要太在乎版本-當前的客戶端也可以與elasticsearch 2.x一起使用。

但是也有一個缺點–它還沒有很多功能。

該客戶端也可以作為Maven工件使用。

dependencies {compile group: 'org.elasticsearch.client',name: 'rest',version: '5.0.0' }

客戶端僅取決于apache httpclient及其依賴項。 這是所有依賴項的Gradle列表。

+--- org.apache.httpcomponents:httpclient:4.5.2 +--- org.apache.httpcomponents:httpcore:4.4.5 +--- org.apache.httpcomponents:httpasyncclient:4.1.2 +--- org.apache.httpcomponents:httpcore-nio:4.4.5 +--- commons-codec:commons-codec:1.10 \--- commons-logging:commons-logging:1.1.3

可以通過傳入一個或多個HttpHost來實例化它。

RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200, "http"),new HttpHost("localhost", 9201, "http")).build();

由于目前沒有太多功能,因此大多數JSON都只能以String的形式使用。 這是一個執行match_all查詢并使用幫助程序方法將響應轉換為String的示例。

HttpEntity entity = new NStringEntity("{ \"query\": { \"match_all\": {}}}",ContentType.APPLICATION_JSON);// alternative: performRequestAsyncResponse response = restClient.performRequest("POST", "/_search", emptyMap(), entity);String json = toString(response.getEntity());// ...

索引數據也很低。 您只需將包含JSON文檔的String發送到端點。 客戶端支持使用單獨的庫進行嗅探。 除了具有更少的依賴關系并且elasticsearch版本不再那么重要的事實之外,操作還有另一個好處:現在可以將集群與應用程序分離,HTTP是與集群通信的唯一協議。

大多數功能直接取決于Apache http客戶端。 支持使用基本身份驗證,自定義標頭和錯誤處理來設置超時。

目前,尚無查詢支持。 如果您能夠將elasticsearch依賴項添加到您的應用程序中(這當然會使某些好處再次SearchSourceBuilder ),則可以使用SearchSourceBuilder和相關功能為查詢創建字符串。

除了新的RestClient之外,還有另一個具有更多功能的HTTP客戶端:社區構建的客戶端Jest。

笑話

Jest已經存在很長時間了,它是標準客戶端的可行替代方案。 它也可以通過Maven Central獲得。

dependencies {compile group: 'io.searchbox',name: 'jest',version: '2.0.0' }

JestClient是允許將請求發送到JestClient的中央接口。 可以使用工廠創建。

JestClientFactory factory = new JestClientFactory(); factory.setHttpClientConfig(new HttpClientConfig.Builder("http://localhost:9200").multiThreaded(true).build());JestClient client = factory.getObject();

與RestClient一樣,Jest不支持生成查詢。 您可以使用String模板創建它們,也可以重用elasticsearch構建器(缺點是必須再次管理所有依賴項)。

可以使用構建器來創建搜索請求。

String query = jsonStringThatMagicallyAppears;Search search = new Search.Builder(query).addIndex("library").build();SearchResult result = client.execute(search); assertEquals(Integer.valueOf(1), result.getTotal());

可以通過遍歷Gson對象結構來處理結果,該對象可能變得相當復雜。

JsonObject jsonObject = result.getJsonObject(); JsonObject hitsObj = jsonObject.getAsJsonObject("hits"); JsonArray hits = hitsObj.getAsJsonArray("hits"); JsonObject hit = hits.get(0).getAsJsonObject();// ... more boring code

但這不是您通常與Jest合作的方式。 關于Jest的好處是它直接支持索引和搜索Java Bean。 例如,我們可以代表我們的餐具文件。

public class Dish {private String food;private List<String> tags;private Favorite favorite;@JestIdprivate String id;// ... getters and setters }

然后可以從搜索結果中自動填充此類。

Dish dish = result.getFirstHit(Dish.class).source;assertEquals("Roti Prata", dish.getFood());

當然,bean支持也可以用于索引數據。

通過http訪問elasticsearch時,Jest可能是一個很好的選擇。 它具有許多有用的功能,例如在索引和搜索時支持bean,以及一種稱為節點發現的嗅探功能。 不幸的是,您必須自己創建搜索查詢,但RestClient也是如此。

現在我們已經研究了三個客戶端,是時候在更高層次上看到抽象了。

Spring Data Elasticsearch

Spring Data項目家族提供了使用通用編程模型訪問不同數據存儲的權限。 它不會嘗試提供所有商店的抽象,每個商店的特產仍然可用。 最令人印象深刻的功能是動態存儲庫,使您可以使用界面定義查詢。 流行的模塊是用于訪問關系數據庫的Spring Data JPA和Spring Data MongoDB。

像所有Spring模塊一樣,工件可以在Maven Central中使用。

dependencies {compile group: 'org.springframework.data',name: 'spring-data-elasticsearch',version: '2.0.4.RELEASE' }

使用自定義批注將要建立索引的文檔表示為Java Bean。

@Document(indexName = "spring_dish") public class Dish {@Idprivate String id;private String food;private List<String> tags;private Favorite favorite;// more code}

可以使用不同的注釋來定義如何在elasticsearch中存儲文檔。 在這種情況下,我們僅定義持久化文檔時要使用的索引名稱,以及用于存儲由elasticsearch生成的id的屬性。

為了訪問文檔,可以定義一個鍵入到餐具類的接口。 有不同的擴展接口, ElasticsearchCrudRepository提供通用的索引和搜索操作。

public interface DishRepository extends ElasticsearchCrudRepository<Dish, String> {}

該模塊提供用于XML配置的名稱空間。

<elasticsearch:transport-client id="client" /><bean name="elasticsearchTemplate" class="o.s.d.elasticsearch.core.ElasticsearchTemplate"><constructor-arg name="client" ref="client"/> </bean><elasticsearch:repositories base-package="de.fhopf.elasticsearch.springdata" />

transport-client元素實例化了一個傳輸客戶端, ElasticsearchTemplate提供了有關ElasticsearchTemplate的常用操作。 最后, repositories元素指示Spring Data掃描擴展Spring Data接口之一的接口。 它將自動為這些實例創建實例。

然后,您可以將存儲庫連接到應用程序中,并將其用于存儲和查找Dish實例。

Dish mie = new Dish(); mie.setId("hokkien-prawn-mie"); mie.setFood("Hokkien Prawn Mie"); mie.setTags(Arrays.asList("noodles", "prawn"));repository.save(Arrays.asList(hokkienPrawnMie));// one line ommitedIterable<Dish> dishes = repository.findAll();Dish dish = repository.findOne("hokkien-prawn-mie");

通過id檢索文檔對于搜索引擎而言不是很有趣。 要真正查詢文檔,您可以在界面中添加遵循特定命名約定的更多方法。

public interface DishRepository extends ElasticsearchCrudRepository<Dish, String> {List<Dish> findByFood(String food);List<Dish> findByTagsAndFavoriteLocation(String tag, String location);List<Dish> findByFavoritePriceLessThan(Double price);@Query("{\"query\": {\"match_all\": {}}}")List<Dish> customFindAll(); }

大多數方法以findBy開頭,后跟一個或多個屬性。 例如, findByFood將使用給定的參數查詢田間food 。 結構化查詢也是可能的,在這種情況下,通過添加lessThan 。 這將返回所有價格低于給定價格的菜肴。 最后一種方法使用另一種方法。 它不遵循命名約定,而是使用Query注釋。 當然,此查詢也可以包含參數的占位符。

總結一下,Spring Data Elasticsearch是在標準客戶端之上的一個有趣的抽象。 它在某種程度上與某個Elasticsearch版本相關,當前版本使用2.2版。 有計劃使其與5.x兼容,但這可能仍需要一些時間。 有一個拉取請求使用Jest進行通信,但尚不清楚是否以及何時將其合并。 不幸的是,項目中沒有很多活動。

結論

我們研究了三個Java客戶端和更高層次的抽象Spring Data Elasticsearch。 這些中的每一個都有其優點和缺點,并且沒有建議在所有情況下都使用它。 傳輸客戶端具有完整的API支持,但與elasticsearch依賴關系相關。 RestClient是未來,將有一天取代運輸客戶端。 從功能上講,它目前處于較低水平。 Jest具有更豐富的API,但是是外部開發的,盡管項目中的提交者有活動,但Jest背后的公司似乎已不存在。 另一方面,Spring Data Elasticsearch更適合已經使用Spring Data且不希望直接與Elasticsearch API聯系的開發人員。 它當前與標準客戶端的版本綁定,開發活動很少。

翻譯自: https://www.javacodegeeks.com/2016/11/java-clients-elasticsearch-transcript.html

總結

以上是生活随笔為你收集整理的用于Elasticsearch成绩单的Java客户端的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。