一、前言 最近有點想弄一個站內搜索的功能,之前學過了Lucene,後來又聽過Solr這個名詞。接著在瞭解全文搜索的時候就發現了Elasticsearch這個,他也是以Lucene為基礎的。 我去搜了幾篇Elasticsearch教程,發現很多都是基於linux的,但我linux耍得並不熟,很少用。僅 ...
一、前言
最近有點想弄一個站內搜索的功能,之前學過了Lucene,後來又聽過Solr這個名詞。接著在瞭解全文搜索的時候就發現了Elasticsearch這個,他也是以Lucene為基礎的。
我去搜了幾篇Elasticsearch教程,發現很多都是基於linux的,但我linux耍得並不熟,很少用。僅僅會一些簡單的命令,等真正去用到linux的時候再慢慢啃吧。
於是發現了一篇寫得很好的教程:
http://blog.csdn.net/laoyang360/article/details/52244917
首先是對Elasticsearch的安裝,上面那篇教程也有說,並且給出了一鍵安裝的腳本。這裡就用來記錄我個人的安裝歷程吧。
PS:2018年3月22日18:58:12更新:這裡我已經不建議在Windows下裝Elasticsearch了,因為裝起來還是麻煩,也有一堆的小問題~(後面也有在Linux下配置Elasticsearch的過程,建議用linux環境下學習Elasticsearch(要是學生建議去買個伺服器,有優惠的),實在不想出錢,用虛擬機也行~
二、Windows下安裝Elasticsearch(不建議)
2.1安裝Elasticsearch
安裝Elasticsearch以window服務的方式來運行,它的給出的版本是2.3.3。於是我也去安裝2.3.3了。
在官網上可以在搜索框中查找對應的版本
要以windows服務的方式運行,教程給出的鏈接已經掛了。我搜到了一篇
http://www.cnblogs.com/viaiu/p/5715200.html
2.2安裝head
安裝head插件就很簡單了,切換到對應的目錄下,使用如下命令:
plugin install mobz/elasticsearch-head
2.3安裝kibana和Logstash插件以服務形式運行
給出的連接是stackOverFlow下的提問,還有youtobe的視頻。stackOverFlow並不能解決我安裝過程的問題,youtobe我沒聯外網,也進不去。
後來,我又找到了一篇教程,也十分順利:
https://segmentfault.com/a/1190000010741203#articleHeader2
Logstash下載的版本是:2.3.3與Elasticsearch對應起來。
下載kibana的版本是:4.5.0
能夠出現下麵這種情況,說明安裝成功
2.4安裝Shield
plugin install license
plugin install shield
重啟,接著執行:
添加管理員
bin/shield/esusers useradd adminName -r admin
為kibana添加用戶
esusers useradd kibanaserver -r kibana4_server
在其配置上(kibana.yml)添加:
kibana_elasticsearch_username: kibanaserver #Kibana服務將用這個用戶名訪問ElasticSearch伺服器。
kibana_elasticsearch_password: zhongfucheng #密碼
只有配置了kibanaserver賬戶、才能登陸進去
2.5安裝分詞器
這次教程給出的連接就用上了,我截圖主要的:
ik分詞器的版本是1.9.3。文章給出的是以mvn的方式打包下載。因此在github中我們下載resouce類型的。
解壓的時候是在zip解壓到當前文件上,把conf的數據拿過去是將其源文件拿過去(不包括文件夾!)
2.6拼音分詞器
前面下載了中文分詞器,後邊在看教程的時候也發現了拼音分詞器,拼音分詞器的安裝和中文分詞器安裝的時候很類似
對應Elasticsearch2.3.3版本的拼音分詞器版本為:1.7.3
Windows下裝Elasticsearch到此就結束了。
三、Linux下安裝Elasticsearch
這是我搭建一個項目時候的筆記,
3.1下載Elasticsearch
Elasticserach的下載還是非常方便的,提供搜索來進行下載。這裡我就不貼鏈接了。直接去官網找就行了。或者去我的Elasticsearch學習記錄中找。
下載了2.3.3版本,因為我在windows開發的時候也是下載2.3.3版本的,就為了保持一致吧。
3.2安裝Elasticsearch
tar -xzvf elasticsearch-2.3.3.tar.gz
切換到bin目錄下執行就行了...
需要這樣執行elasticsearch,如果使用的是root用戶的話
./elasticsearch -d -Des.insecure.allow.root=true
現在使用下麵的語句,是可以獲取得到信息的
curl -X GET 'http://localhost:9200'
想要通過外網來訪問的話,那麼就需要修改配置文件了,參考鏈接http://blog.csdn.net/u012599988/article/details/51767183
還要在ESC伺服器上開放埠才能訪問:
3.2.1下載head插件
在下載head插件的時候,需要修改elasticsearch的用戶和組,否則它就不讓你下載。命令如下
添加用戶和組
groupadd elasticsearch
useradd elasticsearch -g elasticsearch -p 123456
修改文件夾許可權
chown -R elasticsearch:elasticsearch elasticsearch-2.3.3
弄完之後就可以執行命令下載head插件了。
./plugin install mobz/elasticsearch-head
下載完head插件後,不要立馬下載shield插件,首先在head插件上創建一個索引!
否則,當下載完shield插件、再訪問head插件的話,就無法連接節點了!
這搞了我好長的時間才弄好!!!!!網上也有很多人遇到過這種情況,卻沒什麼好的回答。都在說配置文件上的事情。
我是通過在github中別人提出的issue中找到答案的。參考:https://github.com/mobz/elasticsearch-head/issues/191#issuecomment-132636493
記住了,先在head插件中創建索引、再下載shield插件,否則無法連接head插件!
3.2.2下載許可權shield
我在windows下開發是有下載shiled,為了保持一致,我也下載吧。
輸入命令:
plugin install license
plugin install shield
下載完就配置一個管理員用戶
bin/shield/esusers useradd adminName -r admin
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關註微信公眾號:Java3y
四、REST API
在前面一章中已經下載了Elasticsearch和它常用的各種插件了。瞭解相關的概念後,我們就應該動手弄一弄Elasticsearch是怎麼用的。
參考鏈接:
http://blog.csdn.net/laoyang360/article/details/52244917
我是跟著這個教程大致把REST API走了一下,也漸漸瞭解了Elasticsearch的知識點了。
http://www.yiibai.com/elasticsearch/elasticsearch_installation.html
五、JAVA API
我們畢竟是使用Java的,因此得知道Elasticsearch和Java是怎麼連接的。我找了幾篇教程:
http://www.cnblogs.com/wenbronk/p/6383194.html
http://www.cnblogs.com/tutu21ybz/p/6835178.html
後來找到了一篇比較系統的教程,推薦這個:
http://blog.csdn.net/napoay/article/details/51707023
自己也跟著教程寫了Demo,其中也出了不少錯誤。貼上代碼:
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryAction;
import org.elasticsearch.action.deletebyquery.DeleteByQueryRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.shield.ShieldPlugin;
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import org.elasticsearch.client.transport.TransportClient;
/**
* Created by ozc on 2017/11/5.
*/
public class ElasticsearchDemo {
/**
* 創建
* @throws UnknownHostException
*/
@Test
public void CreateIndex() throws UnknownHostException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
//將數據轉成json字元串,用集合裝載起來
List<String> jsonData = DataFactory.getInitJsonData();
//創建blog索引、article類型、數據是上邊的json字元串
for (int i = 0; i < jsonData.size(); i++) {
IndexResponse response = client.prepareIndex("blog", "article","1").setSource(jsonData.get(i)).get();
if (response.isCreated()) {
System.out.println("創建成功!");
}
}
client.close();
}
/**
* 查詢
* @throws UnknownHostException
*/
@Test
public void selectIndex() throws UnknownHostException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
//查詢title欄位中包含hibernate關鍵字的文檔
QueryBuilder qb1 = termQuery("title", "hibernate");
//查詢title欄位或content欄位中包含git關鍵字的文檔:
QueryBuilder qb2= QueryBuilders.multiMatchQuery("git", "title","content");
SearchResponse response = client.prepareSearch("blog").setTypes("article").setQuery(qb2).execute()
.actionGet();
SearchHits hits = response.getHits();
if (hits.totalHits() > 0) {
for (SearchHit hit : hits) {
System.out.println("score:"+hit.getScore()+":\t"+hit.getSource());// .get("title")
}
} else {
System.out.println("搜到0條結果");
}
}
/**
* 使用updateRequest更新
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void update1() throws IOException, ExecutionException, InterruptedException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
UpdateRequest uRequest = new UpdateRequest();
uRequest.index("blog");
uRequest.type("article");
uRequest.id("1");
uRequest.doc(jsonBuilder().startObject().field("content", "學習目標 掌握java泛型的產生意義ssss").endObject());
client.update(uRequest).get();
}
/**
* 使用腳本更新,需要更改配置文件【我不喜歡用】
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void update2() throws IOException, ExecutionException, InterruptedException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
client.prepareUpdate("blog", "article", "1")
.setScript(new Script("ctx._source.title = \"git入門\"", ScriptService.ScriptType.INLINE, null, null))
.get();
}
/**
* 使用doc更新
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void update3() throws IOException, ExecutionException, InterruptedException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
client.prepareUpdate("blog", "article", "1")
.setDoc(jsonBuilder().startObject().field("content", "SVN與Git對比222222。。。").endObject()).get();
}
/**
* 使用updateRequest更新、能夠新增新欄位
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void update4() throws IOException, ExecutionException, InterruptedException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
UpdateRequest updateRequest = new UpdateRequest("blog", "article", "1")
.doc(jsonBuilder().startObject().field("commet", "0").endObject());
client.update(updateRequest).get();
}
/**
* 使用UpdateRequest更新, 如果文檔不存在則創建新的索引
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void update5() throws IOException, ExecutionException, InterruptedException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
IndexRequest indexRequest = new IndexRequest("blog", "article", "10").source(jsonBuilder().startObject()
.field("title", "Git安裝10").field("content", "學習目標 git。。。10").endObject());
UpdateRequest uRequest2 = new UpdateRequest("blog", "article", "10").doc(
jsonBuilder().startObject().field("title", "Git安裝").field("content", "學習目標 git。。。").endObject())
.upsert(indexRequest);
client.update(uRequest2).get();
}
/**
* 刪除具體的索引值
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void deleteSpecificIndex() throws IOException, ExecutionException, InterruptedException {
//連接客戶端
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
DeleteResponse dResponse = client.prepareDelete("blog", "article", "10").execute()
.actionGet();
if (dResponse.isFound()) {
System.out.println("刪除成功");
} else {
System.out.println("刪除失敗");
}
}
/**
* 根據index名稱 刪除整個索引庫
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void deleteIndex() throws IOException, ExecutionException, InterruptedException {
//要刪除索引庫的名字
String indexName = "zhognfucheng";
if (!isIndexExists(indexName)) {
System.out.println(indexName + " not exists");
} else {
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),
9300));
DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(indexName)
.execute().actionGet();
if (dResponse.isAcknowledged()) {
System.out.println("delete index "+indexName+" successfully!");
}else{
System.out.println("Fail to delete index "+indexName);
}
}
}
// 創建索引庫
@Test
public void createIndex() {
//要創建索引庫的名稱
String indexName = "shcool";
try {
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
// 創建索引庫
if (isIndexExists(indexName)) {
System.out.println("Index " + indexName + " already exits!");
} else {
CreateIndexRequest cIndexRequest = new CreateIndexRequest(indexName);
CreateIndexResponse cIndexResponse = client.admin().indices().create(cIndexRequest)
.actionGet();
if (cIndexResponse.isAcknowledged()) {
System.out.println("create index successfully!");
} else {
System.out.println("Fail to create index!");
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
/**
* 批量從Elasticsearch導出json到文件中
*/
@Test
public void ElasticSearchBulkOut() {
try {
//初始化
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch").build();// cluster.name在elasticsearch.yml
//連接客戶端
Client client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName("127.0.0.1"), 9300));
//匹配所有查詢
QueryBuilder qb = QueryBuilders.matchAllQuery();
SearchResponse response = client.prepareSearch("blog")
.setTypes("article").setQuery(qb)
.execute().actionGet();
//獲取命中記錄
SearchHits resultHits = response.getHits();
//遍歷命中記錄,寫到文件中
File article = new File("C:\\ElasticsearchDemo\\src\\java\\file\\bulk.txt");
FileWriter fw = new FileWriter(article);
BufferedWriter bfw = new BufferedWriter(fw);
if (resultHits.getHits().length == 0) {
System.out.println("查到0條數據!");
} else {
for (int i = 0; i < resultHits.getHits().length; i++) {
String jsonStr = resultHits.getHits()[i]
.getSourceAsString();
System.out.println(jsonStr);
bfw.write(jsonStr);
bfw.write("\n");
}
}
bfw.close();
fw.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 批量導入到Elasticsearch中
*/
@Test
public void ElasticSearchBulkInput() {
try {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch").build();// cluster.name在elasticsearch.yml中配置
Client client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName("127.0.0.1"), 9300));
File article = new File("C:\\ElasticsearchDemo\\src\\java\\file\\bulk.txt");
FileReader fr=new FileReader(article);
BufferedReader bfr=new BufferedReader(fr);
String line = null;
BulkRequestBuilder bulkRequest=client.prepareBulk();
int count=0;
while((line=bfr.readLine())!=null){
bulkRequest.add(client.prepareIndex("test","article").setSource(line));
if (count%10==0) {
bulkRequest.execute().actionGet();
}
count++;
//System.out.println(line);
}
bulkRequest.execute().actionGet();
bfr.close();
fr.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根據名稱判斷索引是否存在
* @param indexName
* @return
*/
public boolean isIndexExists(String indexName) {
boolean flag = false;
try {
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
IndicesExistsRequest inExistsRequest = new IndicesExistsRequest(indexName);
//下麵可判斷多個索引名稱是否存在
//IndicesExistsResponse indexResponse = client.admin().indices().prepareExists("blog","blog1").execute().actionGet();
IndicesExistsResponse inExistsResponse = client.admin().indices()
.exists(inExistsRequest).actionGet();
if (inExistsResponse.isExists()) {
flag = true;
} else {
flag = false;
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
return flag;
}
/**
* 刪除type下的所有文檔
* 也就是類似關係型資料庫中根據表刪除所有記錄
*
* ps(需要下載插件plugin install delete-by-query)和導入pom包
*
* ps(使用的是windows服務的方式運行Elastic,因此需要在bin目錄下的使用service重啟,不然就會報空指針異常!
*/
@Test
public void deleteByQuery() throws UnknownHostException {
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
String deletebyquery = "{\"query\": {\"match_all\": {}}}";
DeleteByQueryRequestBuilder response = new DeleteByQueryRequestBuilder(client,DeleteByQueryAction.INSTANCE);
response.setIndices("blog").setTypes("article").setSource(deletebyquery)
.execute()
.actionGet();
}
//-------------------------------------------------------------------
/**
* Java三層嵌套查詢,我感覺是用得很少的。貼個鏈接把:
* http://blog.csdn.net/napoay/article/details/52060659
* <p>
* 搜索有相同父id的子文檔,我也感覺用得少。貼個鏈接吧:
* http://blog.csdn.net/napoay/article/details/52118408
*
* 集群配置,現在用不上。貼個鏈接吧:
* http://blog.csdn.net/napoay/article/details/52202877
*/
//-------------------------------------------------------------------
/**
* 刪除index為blog、類型為article、id為1的索引中的id屬性
* (需要在配置文件中添加以下內容),否則會出現異常
*
* script.inline: on
script.indexed: on
script.engine.groovy.inline.aggs: on
*
* @throws UnknownHostException
*/
@Test
public void deleteField() throws UnknownHostException {
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
client.prepareUpdate("blog", "article", "1").setScript(new Script("ctx._source.remove(\"title\")",ScriptService.ScriptType.INLINE, null, null)).get();
//刪除屬性中的屬性
//client.prepareUpdate("test", "document", "1").setScript(new Script( "ctx._source.processInstance.remove(\"id\")",ScriptService.ScriptType.INLINE, null, null)).get();
}
/**
* 添加了Elasticsearch安全插件以後,連接cliet的方式就要改變了。
*
* 網站給的maven坐標根本找不到,只能下載了個jar包用了。
*
* 配置了Elasticsearch認證以後,kibana也需要配置,不然進不去的。
*
* 鏈接:
* http://blog.csdn.net/sd4015700/article/details/50427852
*
* 當前配置的Elasticsearch zhongfucheng:zhongfucheng
* 當前配置的kibana kibanaserver:zhongfucheng (ps:此部分還需要修改配置文件,詳情看上邊的連接)
*
*/
@Test
public void changeClient() throws UnknownHostException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
System.out.println(client);
}
/**
* 判斷類型是否存在
* @throws UnknownHostException
*/
@Test
public void isTypeExists() throws UnknownHostException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
// bolg是index、article是類型
TypesExistsResponse typeResponse = client.admin().indices()
.prepareTypesExists("blog").setTypes("article")
.execute().actionGet();
System.out.println(typeResponse.isExists());
}
/**
* 關閉索引
*/
@Test
public void closeIndex() throws UnknownHostException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
CloseIndexResponse cIndexResponse = client.admin().indices().prepareClose("shcool")
.execute().actionGet();
if (cIndexResponse.isAcknowledged()) {
System.out.println("關閉索引成功");
}
}
/**
* 打開索引
* @throws UnknownHostException
*/
@Test
public void openIndex() throws UnknownHostException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
OpenIndexResponse oIndexResponse = client.admin().indices()
.prepareOpen("shcool")
.execute().actionGet();
System.out.println(oIndexResponse.isAcknowledged());
}
/**
* 獲取文檔的集合
* 可以獲取同一索引、同一類型、不同id的文檔集合
* 也可以獲取不同索引、不同類型、不同id的文檔集合
*/
@Test
public void getDocCollection() throws UnknownHostException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
.add("blog", "article", "1") //註釋1
//.add("twitter", "tweet", "2", "3", "4") //註釋2
.add("test", "article", "AV-K5x1NAQtVzQCf247Q") //註釋3
.get();
for (MultiGetItemResponse itemResponse : multiGetItemResponses) { //註釋4
GetResponse response = itemResponse.getResponse();
if (response.isExists()) { //註釋5
String json = response.getSourceAsString(); //註釋6
System.out.println(json);
}
}
/**
註釋1: 通過單一的ID獲取一個文檔.
註釋2:傳入多個id,從相同的索引名/類型名中獲取多個文檔.
註釋3:可以同時獲取不同索引中的文檔.
註釋4:遍歷結果集.
註釋5:檢驗文檔是否存在.
註釋6:獲取文檔源.
*/
}
/**
* 獲取索引下每個Type和Mapping
* @throws IOException
*/
@Test
public void getIndexTypeAndMapping() throws IOException {
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
ImmutableOpenMap<String, MappingMetaData> mappings = client.admin().cluster().prepareState().execute()
.actionGet().getState().getMetaData().getIndices().get("blog").getMappings();
for (ObjectObjectCursor<String, MappingMetaData> cursor : mappings) {
System.out.println(cursor.key); // 索引下的每個type
System.out.println(cursor.value.getSourceAsMap()); // 每個type的mapping
}
}
/**
*
* Elasticsearch還有分析聚合這麼一個功能,類似與Mysql中的分組函數、統計數據。
* 貼個鏈接:
*
* http://blog.csdn.net/napoay/article/details/53484730
*/
}
上面的代碼是到:http://blog.csdn.net/napoay/article/details/53276758為止的。
在練習Demo的時候出現了幾個問題:
- 使用shiled認證,無法下載maven坐標,只能導入jar包(官方給出的maven坐標也找不著....shield被廢棄了)
- 使用shiled認證之後,上面博主給出的連接ElasticSearch代碼有錯,拋出了異常。上網找了幾篇資料,無法解決我的問題:
- http://blog.csdn.net/sd4015700/article/details/50427852
- http://blog.csdn.net/lvyuan1234/article/details/78227778
- 最後在一篇博文中找到了答案:更新連接Elasticsearch的代碼
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("shield.user", "zhongfucheng:zhongfucheng")
.build();
TransportClient client = TransportClient.builder()
.addPlugin(ShieldPlugin.class)
.settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
六、總結
在我的個人項目中簡單用到了Elasticsearch,也遇到了不少的坑,比如:當創建Elasticsearch的Client的時候,一定要加入嗅探這麼一個配置:.put("client.transport.sniff", true)
,否則Elasticsearch在使用的時候會非常非常卡,簡直令人懷疑人生。
當時我是用Elasticsearch做自動補齊的功能的,也就下麵這張圖片:
Elasticsearch有suggest這麼一個自動提示(補齊)的功能,參考博文:
http://blog.csdn.net/gumpeng/article/details/50346631
http://www.tcao.net/article/86.html
http://blog.csdn.net/liyantianmin/article/details/60778273
具體的操作:
- 在建立Mapping的時候創建自動補齊的這麼一個欄位,設置以下的Mapping
//自動補全屬性--------
.startObject("suggestName")
.field("type", "completion")
.field("analyzer", "standard")
.field("payloads", "true")
.endObject()
//自動補全屬性結束--------
當用戶加入新的索引記錄的時候,自動補齊欄位就是我們的關鍵欄位
public static String String2JSON(String... strings) throws IOException {
String suggestName = strings[2];
if (suggestName.length() > 0) {
}
XContentBuilder builder = jsonBuilder()
.startObject()
.field("userId", strings[0])
.field("webSiteAddr", strings[1])
.field("webSiteName", strings[2])
//自動補全欄位
.field("suggestName", strings[2])
.endObject();
return builder.string();
}
其他基礎的東西其實都是Lucene演變過來的,要是沒學過Lucene可以去看看我另外一篇博文:
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關註微信公眾號:Java3y