elasticsearch

1.solr和elasticSearch對比
  
總結:
      1. 兩者安裝都很簡單。

   2.Solr 利用 Zookeeper 進行分佈式管理,而 Elasticsearch 自身帶有分佈式協調管理功能。html

   3.Solr 支持更多格式的數據,好比JSON、XML、CSV,而 Elasticsearch 僅支持json文件格式。java

   4.Solr 官方提供的功能更多,而 Elasticsearch 自己更注重於核心功能,高級功能多有第三方插件提供node

   5.Solr 在傳統的搜索應用中表現好於 Elasticsearch,但在處理實時搜索應用時效率明顯低於 Elasticsearch。數據庫

   6.Solr 是傳統搜索應用的有力解決方案,但 Elasticsearch 更適用於新興的實時搜索應用。編程

     7.Solr專一於文本搜索,而Elasticsearch經常使用於查詢過濾和分組分析統計
2.Elastic 的底層是開源庫 Lucene,須要java8環境,默認9200端口json


3. Elastic默認本機訪問,若是須要遠程訪問,能夠修改 Elastic 安裝目錄的 config/elasticsearch.yml 文件,去掉 network.host 的註釋,將它的值改爲 0.0.0.0 ,而後從新啓動 Elastic。
    network . host : 0.0 . 0.0  (任何人都可訪問,線上改爲具體的ip)
3. Elastic 本質上是一個分佈式數據庫,容許多臺服務器協同工做,每臺服務器能夠運行多個 Elastic 實例。
   Elastic 會索引全部字段,通過處理後寫入一個反向索引(Inverted Index)。查找數據的時候,直接查找該索引。
   Index 裏面單條的記錄稱爲 Document(文檔)。多條 Document 構成了一個 Index。
   Document 能夠分組(Type)是虛擬的邏輯分組,用來過濾 Document,不一樣的 Type 應該有類似的結構(schema)
4.mapping:相似於靜態語言中的數據類型, 做用就是執行一系列的指令將輸入的數據轉成可搜索的索引項(搜索數據的指令集合)
一個mapping由一個或多個analyzer組成, 一個analyzer又由一個或多個filter組成的。當ES索引文檔的時候,它把字段中的內容傳遞給相應的analyzer,analyzer再傳遞給各自的filters。
標準analyzer (默認) , 這個標準analyzer有三個filter:token filter, lowercase filter和stop token filter
   
5. Index:分片(sharding,分片策略)->選定具體的node(Master)Index ->同步到對應的slave node

   Search:從replSet中選定node(負載策略)->請求分發 ->結果集合並api

6.Index、Document等概念
================================================================================
1.數據分類:
   結構化(關係型數據庫)、全文檢索:表:字段數量、字段類型
   非結構化:文本文檔、圖片、視頻、音樂
   半結構化:json、html、xml
2.基於Lucene,倒排索引:每一個Field能夠設置是否保存、是否索引、是否分詞
   添加用戶,並受權
   
  [root@node01 ~]# mkdir /opt/lzx/es
  [root@node01 lzx]# chown lzx:lzx es
  [root@node01 lzx]# yum install unzip -y    安裝unip
  [root@node01 es]# su lzx
  [lzx@node01 es]$ unzip elasticsearch-2.2.1.zip
3.ES內置接口:
  
4.安裝head插件,更好支持REST接口:
  [root@node02 bin]# chown -R lzx /opt/lzx/es/   授予所有權限
  [lzx@node01 bin]$ ./plugin install mobz/elasticsearch-head
  [root@node01 es]# scp -r elasticsearch-2.2.1/ node02:`pwd`
   
爬網頁:wget -o /tmp/wget.log -P /root/data  --no-parent --no-verbose -m -D news.cctv.com   -N --convert-links --random-wait -A html,HTML,shtml,SHTML http://news.cctv.com
@Before
public void createConn() throws Exception {
System.out.printf("---create----------");
Settings settings = Settings.settingsBuilder().put("cluster.name", "lzxcluster").build();
client = TransportClient.builder().settings(settings).build().
addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node01"), 9300)).
addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node02"), 9300)).
addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node03"), 9300));
}

@After
public void closeConn() {
System.out.printf("---close----------");
client.close();
}

@Test
public void createIndex() {
System.out.printf("---create--index--------");
//檢查是否已有索引庫存在
IndicesExistsResponse indicesExistsResponse = client.admin().indices().prepareExists("lzxtest").execute().actionGet();
if (indicesExistsResponse.isExists()) {
client.admin().indices().prepareDelete("lzxtest").execute();
}
Map<String, Object> sets = new HashMap<>();
//設置副本數2
sets.put("number_of_replicas", 2);
client.admin().indices().prepareCreate("lzxtest").setSettings(sets).execute();
}

@Test
public void addData(){
Map<String,Object> dataMap=new HashMap<>();
dataMap.put("name","aaa");
dataMap.put("content","wqlwx is a bad manz");
dataMap.put("size",28);
//prepareIndex(索引庫,類型)
IndexResponse indexResponse=client.prepareIndex("lzxtest","testfields")
.setSource(dataMap)
.execute().actionGet();
System.out.println("id:"+indexResponse.getId());
}

@Test
public void queryData(){
QueryBuilder queryBuilder=new MatchQueryBuilder("content","lzx");
SearchResponse searchResponse=client.prepareSearch("lzxtest")
.setTypes("testfields")
.setQuery(queryBuilder)
.execute()
.actionGet();
SearchHits searchHits= searchResponse.getHits();
System.out.println("總共內容命中次數"+searchHits.getTotalHits());
for (SearchHit searchHit:searchHits){
System.out.println("單個所有內容:"+searchHit.getSourceAsString());
System.out.println("內容:"+searchHit.getSource().get("content"));
}
}

@Test
public void queryDataByPage(){
QueryBuilder queryBuilder=new MatchQueryBuilder("content","lzx");
SearchResponse searchResponse=client.prepareSearch("lzxtest")
.setTypes("testfields")
.addHighlightedField("content") //高亮
.setHighlighterPreTags("<font color=red>")
.setHighlighterPostTags("</font>")
.setQuery(queryBuilder)
.setFrom(0) //起始點
.setSize(2) //查兩個
.execute()
.actionGet();
SearchHits searchHits= searchResponse.getHits();
System.out.println("總共內容命中次數"+searchHits.getTotalHits());
for (SearchHit searchHit:searchHits){
System.out.println("單個所有內容:"+searchHit.getSourceAsString());
System.out.println("內容:"+searchHit.getSource().get("content"));
System.out.println("高亮內容:"+searchHit.getHighlightFields().get("content").getFragments()[0]);
}
}
    1.依賴的包
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-analysis-ik</artifactId>
<version>5.5.1</version>
</dependency>
  1.Java客戶端鏈接Elasticsearch: 客戶端版本應和服務端版本一致
     TransportClient:做爲外部訪問者,請求ES的集羣; 旨在被Java高級REST客戶端取代,執行Http請求而不是序列化的java請求,
     NodeClient:做爲ES集羣的一個節點,其餘節點對其是感知的
     XPackTransportClient:服務裝了x-pack插件
2.TransportClient鏈接:      
/**
* cluster.name:設置ES實例的名稱
* client.transport.sniff:自動嗅探整個集羣的狀態,把集羣中其餘ES節點的ip添加到本地的客戶端列表中
* PreBuiltTransportClient:初始化client較老版本發生了變化,此方法有幾個重載方法,初始化插件等。
* */
Settings esSettings = Settings.builder()
.put("cluster.name", clusterName)
.put("client.transport.sniff", true)
.build();
client = new PreBuiltTransportClient(esSettings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ip), esPort));
/**
* 若是 ElasticSearch 服務安裝了 x-pack 插件,須要 PreBuiltXPackTransportClient 實例才能訪問
* */
Settings settings = Settings.builder().put("cluster.name", "xxx")
.put("xpack.security.transport.ssl.enabled", false)
.put("xpack.security.user", "xxx:xxx")
.put("client.transport.sniff", true).build();
try {
client = new PreBuiltXPackTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("xxx.xxx.xxx.xxx"), 9300))
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("xxx.xxx.xxx.xxx"), 9300));
} catch (UnknownHostException e) {
e.printStackTrace();
}
2. Index API   容許咱們存儲一個 JSON 格式的文檔,使數據能夠被搜索 文檔經過 index type id 惟一肯定。咱們能夠本身提供一個 id ,或者也使用 Index API   爲我 們自動生成一個  。
    四種生成方式:
   a.手動方式,使用原生的byte[]或者String
    
   b.使用Map方式,會自動轉換成與之等價的JSON
    
   c.使用第三方庫來序列化beans,如Jackson
CsdnBlog csdn=new CsdnBlog();
csdn.setTag("C");
csdn.setView("100");
csdn.setTitile("編程");
csdn.setDate(new Date().toString());
ObjectMapper mapper = new ObjectMapper();
byte[] json = mapper.writeValueAsBytes(csdn);
IndexResponse response = client.prepareIndex("fendo", "fendodate").setSource(json).get();
   d.使用內置的幫助類 XContentFactory.jsonBuilder() 
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("user", "ccse")
.field("postDate", new Date())
.field("message", "this is Elasticsearch").endObject();
IndexResponse response = client.prepareIndex("fendo", "fendodata").setSource(builder).get();
還能夠startArray(string)和endArray()方法添加數組。.field()方法能夠接 受多種對象類型。你能夠給它傳遞
數字、日期、甚至其餘XContentBuilder對
2.GetApi:
根據id查詢,operationThreaded 設置爲 true 是在不一樣的線程裏執行這次操做
GetResponse response = client.prepareGet("twitter", "tweet", "1") .setOperationThreaded(false) .get();
3.DelApi:
DeleteResponse response = client.prepareDelete("twitter", "tweet ", "1") .setOperationThreaded(false) .get();  
4.過濾刪除:
BulkByScrollResponse response =
DeleteByQueryAction.INSTANCE.newRequestBuilder(client).filter(QueryBuilders.matchQuery("gender", "male"))//查詢條件
.source("persons") //index(索引名)
.get(); //執行
long deleted = response.getDeleted(); //刪除文檔的數量
  異步方式:
DeleteByQueryAction.INSTANCE.newRequestBuilder(client)
.filter(QueryBuilders.matchQuery("gender", "male")) //查詢
.source("persons") //index(索引名)
.execute(new ActionListener<BulkByScrollResponse>() { //回調監聽
@Override
public void onResponse(BulkByScrollResponse response) {
long deleted = response.getDeleted(); //刪除文檔的數量
}
@Override
public void onFailure(Exception e) {
}
});
Upsert:更新插入
IndexRequest indexRequest = new IndexRequest("index", "type", "1").source(jsonBuilder()
.startObject()
.field("name", "Joe Smith")
.field("gender", "male")
.endObject());
UpdateRequest updateRequest = new UpdateRequest("index", "type", "1").doc(jsonBuilder()
.startObject()
.field("gender", "male")
.endObject())
.upsert(indexRequest); //若是不存在此文檔 ,就增長 `indexRequest`
client.update(updateRequest).get();
多值獲取:一次獲取多個文檔
MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
.add("twitter", "tweet", "1") //一個id的方式
.add("twitter", "tweet", "2", "3", "4") //多個id的方式
.add("another", "type", "foo") //能夠從另一個索引獲取
.get();
for (MultiGetItemResponse itemResponse : multiGetItemResponses) { //迭代返回值
GetResponse response = itemResponse.getResponse();
if (response.isExists()) { //判斷是否存在
String json = response.getSourceAsString(); //_source 字段
}
}


















 


相關文章
相關標籤/搜索