1. 程式人生 > >ElasticSearch 6.1.1 通過Head外掛,新建索引,新增文件,及其查詢資料

ElasticSearch 6.1.1 通過Head外掛,新建索引,新增文件,及其查詢資料

ElasticSearch 6.1.1 通過Head外掛,新建索引,新增文件,及其查詢;

一、首先啟動相關服務:



二、新建一個film索引:



三、建立對映:

1、通過Head外掛:

POST http://192.168.1.111:9200/film/_mapping/dongzuo/

{

    "properties": {

        "title": {

            "type": "text"

        },

        "publishDate": {

            "type": "date"

        },

        "content": {

            "type": "text"

        },

        "director": {

            "type": "keyword"

        },

        "price": {

            "type": "float"

        }

    }

}
title 電影名稱 publishDate 釋出日期 content 簡介 director導演 price 票價

新增文件,資料準備:

public class TestFilm {
	private static String host = "127.0.0.1";
	
	private static int port = 9300;
	
	public TransportClient client = null;
	
	@SuppressWarnings({ "resource", "unchecked" })
	@Before
	public void getClient() throws Exception {
		client = new PreBuiltTransportClient(Settings.EMPTY)
			.addTransportAddress(new TransportAddress(InetAddress.getByName(host),port));
	}
	
	@After
	public void close() {
		if(client!=null) {
			client.close();
		}
	}
	
	/**
	 * 新增文件
	 * @throws Exception
	 */
	@Test
	public void testIndex() throws Exception {
		JsonArray jsonArray = new JsonArray();
		
		JsonObject jsonObject = new JsonObject();
		jsonObject.addProperty("title", "前任3:再見前任");
    	jsonObject.addProperty("publishDate", "2017-12-29");
    	jsonObject.addProperty("content", "一對好基友孟雲(韓庚 飾)和餘飛(鄭愷 飾)跟女友都因為一點小事宣告分手,並且“拒絕挽回,死不認錯”。兩人在夜店、派對與交友軟體上放飛人生第二春,大肆慶祝“黃金單身期”,從而引發了一系列好笑的故事。孟雲與女友同甘共苦卻難逃“五年之癢”,餘飛與女友則棋逢敵手相愛相殺無絕期。然而現實的“打臉”卻來得猝不及防:一對推拉糾結零往來,一對糾纏互懟全交代。兩對戀人都將面對最終的選擇:是再次相見?還是再也不見?");
    	jsonObject.addProperty("director", "田羽生");
    	jsonObject.addProperty("price", "35");
    	jsonArray.add(jsonObject);
    	
    	
    	JsonObject jsonObject2=new JsonObject();
    	jsonObject2.addProperty("title", "機器之血");
    	jsonObject2.addProperty("publishDate", "2017-12-29");
    	jsonObject2.addProperty("content", "2007年,Dr.James在半島軍火商的支援下研究生化人。研究過程中,生化人安德烈發生基因突變大開殺戒,將半島軍火商殺害,並控制其組織,接管生化人的研究。Dr.James僥倖逃生,只好尋求警方的保護。特工林東(成龍 飾)不得以離開生命垂危的小女兒西西,接受證人保護任務...十三年後,一本科幻小說《機器之血》的出版引出了黑衣生化人組織,神祕駭客李森(羅志祥 飾)(被殺害的半島軍火商的兒子),以及隱姓埋名的林東,三股力量都開始接近一個“普通”女孩Nancy(歐陽娜娜 飾)的生活,想要得到她身上的祕密。而黑衣人幕後受傷隱藏多年的安德烈也再次出手,在多次纏鬥之後終於抓走Nancy。林東和李森,不得不以身犯險一同前去解救,關鍵時刻卻發現李森竟然是被殺害的半島軍火商的兒子,生化人的實驗記錄也落入了李森之手......");
    	jsonObject2.addProperty("director", "張立嘉");
    	jsonObject2.addProperty("price", "45");
    	jsonArray.add(jsonObject2);
    	
    	JsonObject jsonObject3=new JsonObject();
    	jsonObject3.addProperty("title", "星球大戰8:最後的絕地武士");
    	jsonObject3.addProperty("publishDate", "2018-01-05");
    	jsonObject3.addProperty("content", "《星球大戰:最後的絕地武士》承接前作《星球大戰:原力覺醒》的劇情,講述第一軍團全面侵襲之下,蕾伊(黛西·雷德利 Daisy Ridley 飾)、芬恩(約翰·博耶加 John Boyega 飾)、波·達默龍(奧斯卡·伊薩克 Oscar Isaac 飾)三位年輕主角各自的抉 擇和冒險故事。前作中覺醒強大原力的蕾伊獨自尋訪隱居的絕地大師盧克·天行者(馬克·哈米爾 Mark Hamill 飾),在後者的指導下接受原力訓練。芬恩接受了一項幾乎不可能完成的任務,為此他不得不勇闖敵營,面對自己的過去。波·達默龍則要適應從戰士向領袖的角色轉換,這一過程中他也將接受一些血的教訓。");
    	jsonObject3.addProperty("director", "萊恩·約翰遜");
    	jsonObject3.addProperty("price", "55");
    	jsonArray.add(jsonObject3);
    	
    	JsonObject jsonObject4=new JsonObject();
    	jsonObject4.addProperty("title", "羞羞的鐵拳");
    	jsonObject4.addProperty("publishDate", "2017-12-29");
    	jsonObject4.addProperty("content", "靠打假拳混日子的艾迪生(艾倫 飾),本來和正義感十足的體育記者馬小(馬麗 飾)是一對冤家,沒想到因為一場意外的電擊,男女身體互換。性別錯亂後,兩人互坑互害,引發了拳壇的大地震,也揭開了假拳界的祕密,惹來一堆麻煩,最終兩人在“卷蓮門”副掌門張茱萸(沈騰 飾)的指點下,向惡勢力揮起了羞羞的鐵拳。");
    	jsonObject4.addProperty("director", "宋陽 / 張吃魚");
    	jsonObject4.addProperty("price", "35");
    	jsonArray.add(jsonObject4);
    	
    	JsonObject jsonObject5=new JsonObject();
    	jsonObject5.addProperty("title", "戰狼2");
    	jsonObject5.addProperty("publishDate", "2017-07-27");
    	jsonObject5.addProperty("content", "故事發生在非洲附近的大海上,主人公冷鋒(吳京 飾)遭遇人生滑鐵盧,被“開除軍籍”,本想漂泊一生的他,正當他打算這麼做的時候,一場突如其來的意外打破了他的計劃,突然被捲入了一場非洲國家叛亂,本可以安全撤離,卻因無法忘記曾經為軍人的使命,孤身犯險衝回淪陷區,帶領身陷屠殺中的同胞和難民,展開生死逃亡。隨著鬥爭的持續,體內的狼性逐漸復甦,最終孤身闖入戰亂區域,為同胞而戰鬥。");
    	jsonObject5.addProperty("director", "吳京");
    	jsonObject5.addProperty("price", "38");
    	jsonArray.add(jsonObject5);
    	
    	for (int i = 0; i < jsonArray.size(); i++) {
			JsonObject jo = jsonArray.get(i).getAsJsonObject();
			IndexResponse response = client.prepareIndex("film", "dongzuo")
					.setSource(jo.toString(),XContentType.JSON).get();
			
			System.out.println("索引名稱:"+response.getIndex());
    		System.out.println("型別:"+response.getType());
    		System.out.println("文件ID:"+response.getId());
    		System.out.println("當前例項狀態:"+response.status());
		}
	}
}
執行完成後, Head外掛裡面重新整理就能看到資料,圖片略;

四、通過Head外掛查詢資料及其Java程式碼實現

GET http://192.168.1.111:9200/film/dongzuo/_search/   圖片略;

程式碼實現如下:

/**
	 * 查詢所有文件
	 * @throws Exception
	 */
	@Test
	public void searchAll() throws Exception {
		SearchRequestBuilder srb = client.prepareSearch("film")
				.setTypes("dongzuo");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())
				.execute().actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行圖片略;

五、通過Head外掛分頁查詢資料及其Java程式碼實現

POST http://192.168.1.111:9200/film/dongzuo/_search/

{
  "from": 0,
  "size": 2
}
返回2條資料;圖片略;

java程式碼如下:

/*
	 * 分頁查詢
	 */
	@Test
	public void searchPaging() throws Exception {
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())
				.setFrom(1)
				.setSize(2)
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行圖片略;

六、通過Head外掛排序查詢資料及其Java程式碼實現

POST:http://192.168.1.111:9200/film/dongzuo/_search/

{
  "sort":[
     {"publishDate":{"order":"desc"}}
  ]
}
圖片略;

根據釋出日期降序排列;

Java程式碼如下:

/**
	 * 查詢排序
	 */
	@Test
	public void searchOrderBy() throws Exception {
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())
				.addSort("publishDate",SortOrder.DESC)
				.execute()
				.actionGet(); //分頁排序所有
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行圖片略;

七、通過Head外掛實現資料列過濾及其Java程式碼實現

POST http://192.168.1.111:9200/film/dongzuo/_search/

{
  "from": 0,
  "size": 2,
  "_source":{
    "include":["title","price"]
  }
}
執行圖片略;

Java程式碼如下:

/**
	 * 過濾查詢,顯示指定列
	 */
	@Test
	public void searchInclude() throws Exception {
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())
				.setFetchSource(new String[]{"title","price"},null)
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行結果略;

八、通過Head外掛實現簡單條件查詢及其Java程式碼實現

POST:http://192.168.1.111:9200/film/dongzuo/_search/

{
  "query":{
     "match":{"title":"戰"}
  }
}
執行圖片略;

Java程式碼如下:

/**
	 * 條件查詢:模糊查詢
	 */
	@Test
	public void searchByCondition() throws Exception {
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchQuery("title","戰"))
				.setFetchSource(new String[]{"title","price"},null)
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行結果略;

九、通過Head外掛根據條件查詢高亮實現及其Java程式碼實現

POST:http://192.168.1.111:9200/film/dongzuo/_search/

{
  "query":{
     "match":{"title":"戰"}
  },
  "_source":{
    "include":["title","price"]
  },
  "highlight":{
      "fields":{"title":{}}
   }
}
執行圖片略;

Java程式碼如下:

/**
	 * 條件查詢高亮實現
	 */
	@Test
	public void searchHighlight() throws Exception{
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.preTags("<h2>");
		highlightBuilder.postTags("</h2>");
		highlightBuilder.field("title");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchQuery("title", "戰"))
				.highlighter(highlightBuilder)
				.setFetchSource(new String[]{"title","price"},null)
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
			System.out.println(searchHit.getHighlightFields());
			System.out.println("-------結束---------");
		}
	}
執行結果略;

十、通過Head外掛實現組合多條件查詢及其Java程式碼實現

實際專案開發中,基本上都是組合多條件查詢。
ElasticSearch提供bool來實現這種需求;
主要引數:
must:文件 必須 匹配這些條件才能被包含進來。
must_not:文件 必須不 匹配這些條件才能被包含進來。
should:如果滿足這些語句中的任意語句,將增加 _score ,否則,無任何影響。它們主要用於修正每個文件的相關性得分。
filter:必須 匹配,但它以不評分、過濾模式來進行。這些語句對評分沒有貢獻,只是根據過濾標準來排除或包含文件。
最簡單的 模糊查詢標題含有“戰”:
post:http://192.168.1.111:9200/film/dongzuo/_search/

{
  "query": {
    "bool": {
      "must":{"match":{"title":"戰"}}
    }
  }
}
執行結果略;

多條件的話:

{
  "query": {
    "bool": {
      "must":[
		{"match":{"title":"戰"}},
		{"match":{"content":"星球"}}
	  ]
    }
  }
}

執行結果略;

Java程式碼實現如下:

/**
	 * 多條件查詢1
	 */
	@Test
	public void searchMutil() throws Exception{
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("title", "戰");
		QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("content", "星球");
		SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()
				.must(queryBuilder)
				.must(queryBuilder2))
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行結果略;

must_not使用
內容裡不含有“武士”

{
  "query": {
    "bool": {
      "must":{"match":{"title":"戰"}},
      "must_not":{"match":{"content":"武士"}}
    }
  }
}
執行結果略;

Java程式碼實現如下:

/**
	 * 多條件查詢2
	 */
	@Test
	public void searchMutil2() throws Exception{
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("title", "戰");
		QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("content", "武士");
		SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()
				.must(queryBuilder)
				.mustNot(queryBuilder2))
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
should使用 提高得分;
{
  "query": {
    "bool": {
      "must":[
		{"match":{"title":"戰"}}
	  ]
    }
  }
}
執行結果略;

should的使用:

{
  "query": {
    "bool": {
      "must":{"match":{"title":"戰"}},
	  "should":[
		{"match":{"content":"星球"}},
		{"range":{"publishDate":{"gte":"2018-01-01"}}}
	  ]
    }
  }
}
Java程式碼實現:
/**
	 * 多條件查詢3
	 */
	@Test
	public void searchMutil3() throws Exception{
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("title", "戰");
		QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("content", "星球");
		QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("publishDate").gt("2018-01-01");
		
		SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()
				.must(queryBuilder)
				.should(queryBuilder2)
				.should(queryBuilder3))
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}

filter過濾;
票價必須少於40

{
	"query": {
		"bool": {
			"must": {
				"match": {"title": "戰"}
			},
			"filter": {
				"range": {"price": {"lte":"40"}}
			}
		}
	}
}
Java程式碼如下:
/**
	 * 多條件查詢4
	 */
	@Test
	public void searchMutil4() throws Exception{
		SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");
		QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("title", "戰");
		QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("price").lte(40);
		
		SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()
				.must(queryBuilder)
				.filter(queryBuilder2))
				.execute()
				.actionGet();
		SearchHits hits = sr.getHits();
		for (SearchHit searchHit : hits) {
			System.out.println(searchHit.getSourceAsString());
		}
	}
執行結果略;