ElasticSearch初学者教程
1.簡介
在此示例中,我們將演示如何使用Elasticsearch , Elasticsearch是一個基于Apache Lucene的分布式自由文本搜索和分析數據庫引擎,具有一個基于maven的簡單Java客戶端。
在撰寫本文時,我們將使用最新版本的Elasticsearch,即ES v6.1.2。 對于此示例,我們使用以下技術:
- Maven 3
- Java 8
- Elasticsearch 6.1.2
Elasticsearch因其通過RESTful API進行通信的能力而聞名。
這意味著我們將使用API??以及HTTP方法(如GET,POST,PUT和DELETE)與數據庫進行交互。
它是一個高度可擴展的分布式數據庫,可使用Apache Lucene出色地實現。
有關Elasticsearch的其他一些功能包括:
- Elasticsearch的總依賴項大小僅為300 KB,非常輕巧
- Elasticsearch僅專注于查詢的性能。 這意味著無論對數據庫執行什么操作,它們都經過高度優化和可擴展
- 這是一個高度容錯的系統。 如果集群中有單個Elasticsearch節點死亡,則主服務器將非常Swift地確定問題,并將傳入的請求盡快路由到新節點
- Elasticsearch的專長在于可索引文本數據,可根據標記和過濾器進行搜索
盡管當使用分布式自由文本搜索和分析引擎時,Elasticsearch是一個不錯的選擇,但在進行其他一些操作時,它可能不是最適合的數據庫:
- 計算總數和平均值之類的運算
- 使用回滾執行事務查詢
- 管理在多個給定條件下唯一的記錄
這意味著Elasticsearch是一個基于用例的高度數據庫,但就其自己的領域而言卻是一個出色的數據庫。
2.先決條件
因為maven是Java工具,所以您必須在計算機上安裝Java才能繼續。 您可以在此處下載Java。
一旦在系統上安裝了Java,就必須安裝maven。 您可以從此處下載Maven。
最后,您需要安裝Elasticsearch。 您可以從此處下載它,然后按照適用于您的操作系統的步驟進行操作。 請注意,本課程將使用v6.1.2。 現在,其他版本可能會以完全相同的方式工作。 您可以通過在瀏覽器中打開以下URL來驗證ES是否正在運行:
localhost:9200您應該得到如下響應:
{"name": "wKUxRAO","cluster_name": "elasticsearch","cluster_uuid": "gvBXz7xsS5W4zlZuiADelw","version": {"number": "6.1.2","build_hash": "5b1fea5","build_date": "2018-01-10T02:35:59.208Z","build_snapshot": false,"lucene_version": "7.1.0","minimum_wire_compatibility_version": "5.6.0","minimum_index_compatibility_version": "5.0.0"},"tagline": "You Know, for Search" }請注意, elasticsearch是Elasticsearch中的默認集群名稱。
3.項目設置
我們將使用許多Maven原型之一為我們的示例創建一個示例項目。 要創建項目,請在將用作工作空間的目錄中執行以下命令:
mvn archetype:generate -DgroupId=com.javacodegeeks.example -DartifactId=jcg-elasticsearch-example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false如果您是第一次運行maven,則完成生成命令將花費幾秒鐘,因為maven必須下載所有必需的插件和工件才能完成生成任務。
請注意,現在,您將在所選目錄中擁有一個與artifactId同名的新目錄。 現在,隨時在您喜歡的IDE中打開項目。
4. Maven依賴
首先,我們需要在項目中添加適當的Maven依賴項。 我們將以下依賴項添加到我們的pom.xml文件中:
pom.xml
<properties><elasticsearch.version>6.1.2</elasticsearch.version><jackson.version>2.9.4</jackson.version><java.version>1.8</java.version> </properties><dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>${elasticsearch.version}</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>${elasticsearch.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency> </dependencies>在此處找到最新的Elasticsearch依賴項。
請注意,我們在代碼中僅將Jackson用作Java的標準JSON庫。
5.進行數據庫查詢
現在,我們準備開始構建項目并向其中添加更多組件。
5.1建立模型
我們將在我們的項目中添加一個非常簡單的模型,即Person。 它的定義將非常標準,例如:
人.java
public class Person {private String personId;private String name;//standard getters and setters@Overridepublic String toString() {return String.format("Person{personId='%s', name='%s'}", personId, name);} }為了簡潔起見,我們省略了標準的getter和setter方法,但是由于Jackson在對象的序列化和反序列化過程中使用它們,因此必須將它們制成。
5.2定義連接參數
我們將使用默認的連接參數與Elasticsearch建立連接。 默認情況下,ES使用兩個端口:9200和9201。
連接參數
//The config parameters for the connection private static final String HOST = "localhost"; private static final int PORT_ONE = 9200; private static final int PORT_TWO = 9201; private static final String SCHEME = "http";private static RestHighLevelClient restHighLevelClient; private static ObjectMapper objectMapper = new ObjectMapper();private static final String INDEX = "persondata"; private static final String TYPE = "person";除了連接配置參數外,我們還在上面定義了索引參數,以標識我們的Person數據的存儲位置。
如以上參數所述,Elasticsearch使用兩個端口9200和9201。第一個端口9200由Elasticsearch Query Server使用,我們可以使用它們通過RESTful API直接查詢數據庫。 REST服務器使用第二個端口9201 ,外部客戶端可以通過該端口連接并執行操作。
5.3建立連接
我們將提供一種方法來建立與Elasticsearch數據庫的連接。 與數據庫建立連接時,我們必須提供兩個端口,因為只有這樣,我們的應用程序才能連接到Elasticsearch服務器,并且我們將能夠執行數據庫操作。 這是建立連接的代碼:
用于獲取連接對象的Singleton方法
/*** Implemented Singleton pattern here* so that there is just one connection at a time.* @return RestHighLevelClient*/ private static synchronized RestHighLevelClient makeConnection() {if(restHighLevelClient == null) {restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost(HOST, PORT_ONE, SCHEME),new HttpHost(HOST, PORT_TWO, SCHEME)));}return restHighLevelClient; }請注意,我們在此處實現了Singleton Design模式 ,這樣就不會為ES建立多個連接,從而節省了大量內存。
由于存在RestHighLevelClient ,因此與Elasticsearch的連接是線程安全的。 初始化此連接的最佳時間是在應用程序請求或向客戶端發出第一個請求時。 初始化此連接客戶端后,即可用于執行任何受支持的API。
5.4關閉連接
就像在舊版本的Elasticsearch中一樣,我們使用TransportClient并在完成查詢后將其關閉,并且在數據庫與RestHighLevelClient的交互完成后也需要關閉連接。 這是可以做到的:
緊密連接
private static synchronized void closeConnection() throws IOException {restHighLevelClient.close();restHighLevelClient = null; }我們還為RestHighLevelClient對象分配了null,以便Singleton模式可以保持一致。
5.5插入數據
通過將鍵和值轉換為Hashmap,可以將數據插入數據庫。 ES數據庫僅接受HashMap形式的值。 讓我們看一下如何實現這一點的代碼片段:
POST查詢
private static Person insertPerson(Person person){person.setPersonId(UUID.randomUUID().toString());Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put("personId", person.getPersonId());dataMap.put("name", person.getName());IndexRequest indexRequest = new IndexRequest(INDEX, TYPE, person.getPersonId()).source(dataMap);try {IndexResponse response = restHighLevelClient.index(indexRequest);} catch(ElasticsearchException e) {e.getDetailedMessage();} catch (java.io.IOException ex){ex.getLocalizedMessage();}return person; }上面,我們還使用Java的UUID類來創建對象的唯一標識符。 這樣,我們可以控制如何制作對象的標識符。
5.6發出GET請求
將數據插入數據庫后,我們可以通過向Elasticsearch數據庫服務器發出GET請求來確認操作。 讓我們看一下如何做到這一點的代碼片段:
GET查詢
private static Person getPersonById(String id){GetRequest getPersonRequest = new GetRequest(INDEX, TYPE, id);GetResponse getResponse = null;try {getResponse = restHighLevelClient.get(getPersonRequest);} catch (java.io.IOException e){e.getLocalizedMessage();}return getResponse != null ?objectMapper.convertValue(getResponse.getSourceAsMap(), Person.class) : null; }在此查詢中,我們僅提供了有關可用來識別對象的主要信息,即索引,類型及其唯一標識符。 同樣,我們得到的實際上是一個值映射,如以下表達式所示:
獲取地圖
getResponse.getSourceAsMap()實際上是Jackson的objectMapper,用于將該Map轉換為可以在我們的程序中輕松使用的POJO Object,這樣,我們不必每個Map都構成鍵,當您可以時,這將是一個繁瑣的過程只是有一個POJO對象。
5.7更新數據
我們可以通過首先使用索引,類型和唯一標識符標識資源來輕松地向Elasticsearch發出更新請求。 然后,我們可以使用新的HashMap對象來更新Object中任意數量的值。 這是一個示例代碼片段:
PUT查詢
private static Person updatePersonById(String id, Person person){UpdateRequest updateRequest = new UpdateRequest(INDEX, TYPE, id).fetchSource(true); // Fetch Object after its updatetry {String personJson = objectMapper.writeValueAsString(person);updateRequest.doc(personJson, XContentType.JSON);UpdateResponse updateResponse = restHighLevelClient.update(updateRequest);return objectMapper.convertValue(updateResponse.getGetResult().sourceAsMap(), Person.class);}catch (JsonProcessingException e){e.getMessage();} catch (java.io.IOException e){e.getLocalizedMessage();}System.out.println("Unable to update person");return null; }請注意以下語句中我們在上面所做的操作:
PUT查詢
updateRequest.doc(personJson, XContentType.JSON);在這里,我們沒有傳遞需要更新的對象的任何特定屬性,而是傳遞了完整的Object JSON,它將替換該對象存在的每個鍵。
我們還通過catch語句檢查了任何可能的錯誤。 在實際的應用程序中,您將需要適當地處理這些錯誤并制作記錄的日志。
5.8刪除數據
最后,我們可以通過簡單地用索引,類型和唯一標識符標識資源來刪除數據。 讓我們看一下如何做到這一點的代碼片段:
刪除查詢
private static void deletePersonById(String id) {DeleteRequest deleteRequest = new DeleteRequest(INDEX, TYPE, id);try {DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest);} catch (java.io.IOException e){e.getLocalizedMessage();} }同樣,在上面的DELETE查詢中,我們僅提到了如何識別對象。
5.9運行應用程序
讓我們通過執行上面提到的所有操作來嘗試我們的應用程序。 由于這是一個普通的Java應用程序,因此我們將調用以下每個方法并打印操作結果:
main()方法
public static void main(String[] args) throws IOException {makeConnection();System.out.println("Inserting a new Person with name Shubham...");Person person = new Person();person.setName("Shubham");person = insertPerson(person);System.out.println("Person inserted --> " + person);System.out.println("Changing name to `Shubham Aggarwal`...");person.setName("Shubham Aggarwal");updatePersonById(person.getPersonId(), person);System.out.println("Person updated --> " + person);System.out.println("Getting Shubham...");Person personFromDB = getPersonById(person.getPersonId());System.out.println("Person from DB --> " + personFromDB);System.out.println("Deleting Shubham...");deletePersonById(personFromDB.getPersonId());System.out.println("Person Deleted");closeConnection(); }使用代碼運行此應用程序后,將獲得以下輸出:
節目輸出
Inserting a new Person with name Shubham... Person inserted --> Person{personId='bfc5ba80-832a-4925-9b8d-525a4e420cb0', name='Shubham'} Changing name to `Shubham Aggarwal`... Unable to update person Person updated --> Person{personId='bfc5ba80-832a-4925-9b8d-525a4e420cb0', name='Shubham Aggarwal'} Getting Shubham... Person from DB -->Person{personId='bfc5ba80-832a-4925-9b8d-525a4e420cb0', name='Shubham Aggarwal'} Deleting Shubham... Person Deleted當然,ID可以有所不同。 請注意,在完成查詢后,我們關閉了連接。 這有助于JVM收回由ES連接保留的內存。
六,結論
在本課程中,我們研究了如何將Elasticsearch與使用REST客戶端的普通Java客戶端一起使用。 需要使用一個可擴展的示例來探討選擇使用REST客戶端使其在實際應用程序中可用。 這是我們開始構建應用程序時需要做出的選擇。
在我們的Elasticsearch課程中進一步探索Elasticsearch 。
7.下載完整的源代碼
這是有關ElasticSearch REST客戶端和Java查詢的教程,我們通過RESTful操作與Elasticsearch數據庫進行了交互。
下載您可以在此處下載此示例的完整源代碼: Elasticsearch示例
翻譯自: https://www.javacodegeeks.com/2018/03/elasticsearch-tutorial-beginners.html
總結
以上是生活随笔為你收集整理的ElasticSearch初学者教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软 Surface Laptop Go
- 下一篇: 联合创新推出 27C1U PRO 4K