设置虚拟机的内存>1.5G【重启】
创建admin
切换admin
解压安装包【admin】
修改elasticsearch.yml、jvm.options[admin]
解决文件创建权限、内存问题[root]
启动:
./elasticsearch
./elasticsearch -d关闭:
ctrl+c
或
ps-ef|grep elasticsearch
kill -9 pid
在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。
解压IK分词器压缩包,并将解压的文件拷贝到ES安装目录的plugins下的ik(重命名)目录下,重启es
IKAnalyzer.cfg.xml:配置扩展词典和停用词典
main.dic:扩展词典,例如:奥利给
stopword.dic:停用词典,例如:a、an、the、的、地、得注意:扩展词典和停用词典必须另存为UTF-8
ik_max_word:细粒度
ik_smart:粗粒度
PUT /java2104
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 0
}
}
注意:一台服务器时,备份分片数量设置为0
DELETE /java2104
POST /java2104/course/_mapping
{
"properties": {
"name":{
"type": "text"
},
"description":{
"type": "text"
},
"studymodel":{
"type": "keyword"
}
}
}
POST /java2104/course
{
"name":".net从入门到放弃",
"description":".net程序员谁都不服",
"studymodel":"201003"
}
PUT /java2104/course/2
{
"name":"php从入门到放弃",
"description":"php是世界上最好的语言",
"studymodel":"201001"
}
DELETE /java2104/course/2
GET /java2104/course/1
DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求,DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。
GET /java1906/course/_search
{
"query" : {
"match_all" : {}
}
}
GET /test_index/my_type/_search
{
"query" : { "match_all" : {} },
"from" : 1, # 从第几条数据开始查询,从0开始计数
"size" : 2, # 查询多少数据
"sort" : [
{ "order_no" : "asc" }
]
}
query:搜索的关键字
operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。
基本使用:
GET /java1906/course/_search
{
"query" : {
"match" : {
"name": {
"query": "spring开发"
}
}
}
}
operator:
GET /java1906/course/_search
{
"query" : {
"match" : {
"name": {
"query": "spring开发",
"operator": "and"
}
}
}
}
matchQuery是在一个field中去匹配,multiQuery是拿关键字去多个Field中匹配。
GET /java1906/course/_search
{
"query": {
"multi_match": {
"query": "开发",
"fields": ["name","description"]
}
}
}
布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。
参数:
- must:表示必须,多个查询条件必须都满足。(通常使用must)
- should:表示或者,多个查询条件只要有一个满足即可。
- must_not:表示非。
GET /java1906/course/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "开发"
}
},
{
"range": {
"price": {
"gte": 50,
"lte": 100
}
}
}
]
}
}
}
过滤查询。此操作实际上就是 query DSL 的补充语法。过滤的时候,不进行任何的匹配分数计算,相对于 query 来说,filter 相对效率较高。Query 要计算搜索匹配相关度分数。Query更加适合复杂的条件搜索。
不使用 filter, name和price需要计算相关度分数:
GET /java1906/course/_search
{
"query": {
"bool" : {
"must":[
{
"match": {
"name": "开发"
}
},
{
"range": {# 范围, 字段的数据必须满足某范围才有结果。
"price": {
"gte": 1, # 比较符号 lt gt lte gte
"lte": 100
}
}
}
]
}
}
}
使用 filter, price不需要计算相关度分数:
GET /java1906/course/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "开发"
}
}
],
"filter": {# 过滤,在已有的搜索结果中进行过滤,满足条件的返回。
"range": {
"price": {
"gte": 1,
"lte": 100
}
}
}
}
}
}
高亮显示:高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对搜索关键字实现高亮显示。
GET /java1906/course/_search
{
"query": {
"match": {
"name": "开发"
}
},
"highlight": {
"pre_tags": [""],
"post_tags": [""],
"fields": {"name": {}}
}
}
PUT /java2104
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 0
}
}
注意:一台服务器时,备份分片数量设置为0
DELETE /java2104
POST /java2104/course/_mapping
{
"properties": {
"name":{
"type": "text"
},
"description":{
"type": "text"
},
"studymodel":{
"type": "keyword"
}
}
}
POST /java2104/course
{
"name":".net从入门到放弃",
"description":".net程序员谁都不服",
"studymodel":"201003"
}
PUT /java2104/course/2
{
"name":"php从入门到放弃",
"description":"php是世界上最好的语言",
"studymodel":"201001"
}
DELETE /java2104/course/2
GET /java2104/course/1
DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求,DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。
GET /java1906/course/_search
{
"query" : {
"match_all" : {}
}
}
GET /test_index/my_type/_search
{
"query" : { "match_all" : {} },
"from" : 1, # 从第几条数据开始查询,从0开始计数
"size" : 2, # 查询多少数据
"sort" : [
{ "order_no" : "asc" }
]
}
query:搜索的关键字
operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。
基本使用:
GET /java1906/course/_search
{
"query" : {
"match" : {
"name": {
"query": "spring开发"
}
}
}
}
operator:
GET /java1906/course/_search
{
"query" : {
"match" : {
"name": {
"query": "spring开发",
"operator": "and"
}
}
}
}
matchQuery是在一个field中去匹配,multiQuery是拿关键字去多个Field中匹配。
GET /java1906/course/_search
{
"query": {
"multi_match": {
"query": "开发",
"fields": ["name","description"]
}
}
}
布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。
参数:
- must:表示必须,多个查询条件必须都满足。(通常使用must)
- should:表示或者,多个查询条件只要有一个满足即可。
- must_not:表示非。
GET /java1906/course/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "开发"
}
},
{
"range": {
"price": {
"gte": 50,
"lte": 100
}
}
}
]
}
}
}
过滤查询。此操作实际上就是 query DSL 的补充语法。过滤的时候,不进行任何的匹配分数计算,相对于 query 来说,filter 相对效率较高。Query 要计算搜索匹配相关度分数。Query更加适合复杂的条件搜索。
不使用 filter, name和price需要计算相关度分数:
GET /java1906/course/_search
{
"query": {
"bool" : {
"must":[
{
"match": {
"name": "开发"
}
},
{
"range": {# 范围, 字段的数据必须满足某范围才有结果。
"price": {
"gte": 1, # 比较符号 lt gt lte gte
"lte": 100
}
}
}
]
}
}
}
使用 filter, price不需要计算相关度分数:
GET /java1906/course/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "开发"
}
}
],
"filter": {# 过滤,在已有的搜索结果中进行过滤,满足条件的返回。
"range": {
"price": {
"gte": 1,
"lte": 100
}
}
}
}
}
}
高亮显示:高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对搜索关键字实现高亮显示。
GET /java1906/course/_search
{
"query": {
"match": {
"name": "开发"
}
},
"highlight": {
"pre_tags": [""],
"post_tags": [""],
"fields": {"name": {}}
}
}
head插件是ES的一个可视化管理插件,用来监视ES的状态,并通过head客户端和ES服务进行交互,比如创建映射、创建索引等。从ES6.0开始,head插件支持使得node.js运行。
下载地址:https://github.com/mobz/elasticsearch-head
npm run start
Kibana是ES提供的一个基于Node.js的基于Node.js的管理控制台, 可以很容易实现高级的数据分析和可视化,以图标的形式展现出来。
kibana可以用来编辑请求语句,方便学习操作es的语法。有时在进行编写程序,写到查询语句时,往往我会使用kibana进行书写,然后再粘贴到程序中。(不容易出错)
ElasticSearch官网:https://www.elastic.co/cn/
在window中安装Kibana很方便,解压即安装
修改config/kibana.yml配置:
server.port: 5601
server.host: "0.0.0.0" #允许来自远程用户的连接
elasticsearch.url: http://192.168.204.135:9200
./bin/kibana
spring:
data:
elasticsearch:
cluster-nodes: 192.168.233.134:9200
@Configuration
public class ElasticsearchConfig extends ElasticsearchProperties{
@Bean
public RestHighLevelClient getRestHighLevelClient() {
String[] hosts = getClusterNodes().split(",");
HttpHost[] httpHosts = new HttpHost[hosts.length];
for (int i = 0; i < httpHosts.length; i++) {
String h = hosts[i];
httpHosts[i] = new HttpHost(h.split(":")[0],
Integer.parseInt(h.split(":")[1]));
}
return new RestHighLevelClient(RestClient.builder(httpHosts));
}
}
public class IndexWriterTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
//创建索引库
@Test
public void testCreateIndex() throws IOException {
//创建“创建索引请求”对象,并设置索引名称
CreateIndexRequest createIndexRequest = new CreateIndexRequest("java1906");
//设置索引参数
createIndexRequest.settings("{\n" +
" \"number_of_shards\" : 2,\n" +
" \"number_of_replicas\" : 0\n" +
" }", XContentType.JSON);
createIndexRequest.mapping("course", "{\r\n" +
" \"_source\": {\r\n" +
" \"excludes\":[\"description\"]\r\n" +
" }, \r\n" +
" \"properties\": {\r\n" +
" \"name\": {\r\n" +
" \"type\": \"text\",\r\n" +
" \"analyzer\":\"ik_max_word\",\r\n" +
" \"search_analyzer\":\"ik_smart\"\r\n" +
" },\r\n" +
" \"description\": {\r\n" +
" \"type\": \"text\",\r\n" +
" \"analyzer\":\"ik_max_word\",\r\n" +
" \"search_analyzer\":\"ik_smart\"\r\n" +
" },\r\n" +
" \"studymodel\": {\r\n" +
" \"type\": \"keyword\"\r\n" +
" },\r\n" +
" \"price\": {\r\n" +
" \"type\": \"float\"\r\n" +
" },\r\n" +
" \"timestamp\": {\r\n" +
" \"type\": \"date\",\r\n" +
" \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd\"\r\n" +
" }\r\n" +
" }\r\n" +
"}", XContentType.JSON);
//创建索引操作客户端
IndicesClient indices = restHighLevelClient.indices();
//创建响应对象
CreateIndexResponse createIndexResponse =
indices.create(createIndexRequest,RequestOptions.DEFAULT);
//得到响应结果
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println(acknowledged);
}
}
//删除索引库
@Test
public void testDeleteIndex() throws IOException {
//创建“删除索引请求”对象
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("java1906");
//创建索引操作客户端
IndicesClient indices = restHighLevelClient.indices();
//创建响应对象
DeleteIndexResponse deleteIndexResponse =
indices.delete(deleteIndexRequest,RequestOptions.DEFAULT);
//得到响应结果
boolean acknowledged = deleteIndexResponse.isAcknowledged();
System.out.println(acknowledged);
}
//添加文档
@Test
public void testAddDocument() throws IOException {
//创建“索引请求”对象:索引当动词
IndexRequest indexRequest = new IndexRequest("java1906", "course", "1");
indexRequest.source("{\n" +
" \"name\":\"spring cloud实战\",\n" +
" \"description\":\"本课程主要从四个章节进行讲解: 1.微服务架构入门 " +
"2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。\",\n" +
" \"studymodel\":\"201001\",\n" +
" \"price\":5.6\n" +
"}", XContentType.JSON);
IndexResponse indexResponse =
restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
}
@Test
public void testBulkAddDocument() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(new IndexRequest("java1906", "course").source("{...}",
XContentType.JSON));
bulkRequest.add(new IndexRequest("java1906", "course").source("{...}",
XContentType.JSON));
BulkResponse bulkResponse =
restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
System.out.println(bulkResponse.hasFailures());
}
@Test
public void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("java1906", "course", "1");
updateRequest.doc("{\n" +
" \"price\":7.6\n" +
"}", XContentType.JSON);
UpdateResponse updateResponse =
restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
System.out.println(updateResponse.getResult());
}
@Test
public void testDelDocument() throws IOException {
//删除索引请求对象
DeleteRequest deleteRequest = new DeleteRequest("java1906","course","1");
//响应对象
DeleteResponse deleteResponse =
restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
System.out.println(deleteResponse.getResult());
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class IndexSearchTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
private SearchRequest searchRequest;
private SearchResponse searchResponse;
@Before
public void initSearchRequest() {
// 搜索请求对象
searchRequest = new SearchRequest("java1906");
searchRequest.types("course");
}
// 搜索type下的全部记录
@Test
public void testSearchAll() throws Exception {
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
// 设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索
searchResponse =
restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}
@After
public void displayDoc() throws ParseException {
// 搜索匹配结果
SearchHits hits = searchResponse.getHits();
// 搜索总记录数
long totalHits = hits.totalHits;
System.out.println("共搜索到" + totalHits + "条文档");
// 匹配的文档
SearchHit[] searchHits = hits.getHits();
// 日期格式化对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (SearchHit hit : searchHits) {
// 文档id
String id = hit.getId();
System.out.println("id:" + id);
// 源文档内容
String source = hit.getSourceAsString();
System.out.println(source);
}
}
}
//分页查询
@Test
public void testSearchPage() throws Exception {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.from(1);
searchSourceBuilder.size(5);
searchSourceBuilder.sort("price", SortOrder.ASC);
// 设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索
searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}
@Test
public void testMatchQuery() throws Exception {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("name", "spring开
发").operator(Operator.AND));
// 设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索
searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}
@Test
public void testMultiMatchQuery() throws Exception {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("开发","name","description"));
// 设置搜索源
searchRequest.source(searchSourceBuilder);
// 执行搜索
searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}
@Test
public void testBooleanMatch() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//json条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("name","开发"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte("50").lte(100));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(
searchRequest, RequestOptions.DEFAULT);
}
@Test
public void testFilterQuery() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("name","开发"));
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(10).lte(100))
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}
@Test
public void testHighLightQuery() throws Exception {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("name", "spring"));
//设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("");
highlightBuilder.postTags("");
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}
@After
public void displayDoc() {
SearchHits searchHits = searchResponse.getHits();
long totalHits = searchHits.getTotalHits();
System.out.println("共搜索到" + totalHits + "条文档");
SearchHit[] hits = searchHits.getHits();
for (int i = 0; i < hits.length; i++) {
SearchHit hit = hits[i];
String id = hit.getId();
System.out.println("id:" + id);
String source = hit.getSourceAsString();
System.out.println(source);
Map highlightFields = hit.getHighlightFields();
if (highlightFields != null) {
HighlightField highlightField = highlightFields.get("name");
Text[] fragments = highlightField.getFragments();
System.out.println("高亮字段:" + fragments[0].toString());
}
}
}