一、单机版安装
地址:www.elastic.co
下载tar格式,或者复制链接,wget + url下载
启动:
./bin/elasticsearch
二、插件
解决页面问题,GitHub下载:elasticsearch-head
需要node环境。node -v检查node版本,需要大于6.0.0
安装:进入目录,npm install
启动:npm run start,在9100端口启动
head和es存在跨域问题,在es配置文件加配置
#允许跨域
http.cors.enabled: true
http.cors.allow-origin: "*"
三、分布式安装
其中一个设置为master,修改配置文件config/elasticsearch.yml
在最后加上如下配置:
集群配置,master和子节点的配置:
#集群设置
#集群名
cluster.name: wali
#节点名
node.name: master
#指定为master
node.master: true
#绑定IP,本地127.0.0.1
network.host: 127.0.0.1
#子节点配置
#集群名
cluster.name: wali
#本节点名
node.name: slave1
network.host: 127.0.0.1
http.port: 9201
#找到master
discovery.zen.ping.unicast.hosts: ["127.0.0.1"]
四 、基础概念
1、索引 含有相同属性的文档集合
2、类型 所以可以定义一个或多个类型,文档必须鼠疫一个类型
3、文档 文档是可以被索引的及基本数据单位
4、分片 每个索引都有多个分片,每个分片是一个Lucene索引
5、备份 拷贝一份分片就完成了分片的备份
RESTFul API
1、api基本格式:http://<ip>:<port>/<索引>/<类型>/<文档id>
2、常用的HTTP动词 GET/PUT/POST/DELET
索引信息中,mappings为空是非结构化
1、创建索引
创建一个people,put方式
http://192.168.152.128:9200/people
参数:
{
"settings": {
"number_of_shards":3,
"number_of_replicas":1
},
"mappings":{
"man":{
"properties":{
"name":{
"type":"text"
},
"contry":{
"type":"keyword"
},
"age":{
"type":"integer"
},
"date":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
},
"woman":{
}
}
}
2、 插入数据:
指定id,用put,不指定id用post,会自动生成
3、修改
直接修改:http://192.168.152.128:9200/people/man/1/_update
{
"doc":{
"name":"谁是瓦力"
}
}
脚本修改:
{
"script":{
"lang":"painless",
"inline":"ctx._source.age += 1"
}
}
或者:
{
"script":{
"lang":"painless",
"inline":"ctx._source.age =params.age",
"params":{
"age":100
}
}
}
4、删除
删除文档,delete方法:http://192.168.152.128:9200/people/man/1/
删除索引,页面删除:动作-删除;
delete方法:http://192.168.152.128:9200/people
5、查询
根据id查询,get方法:http://192.168.152.128:9200/book/novel/1
http://192.168.152.128:9200/book/_search
match_all:查询所有,from:页数,size:每页条数
{
"query":{
"match_all":{}
},
"from":1,
"size":2
}
条件查询,排序:
{
"query":{
"match":{
"title":"ElasticSearch"
}
},
"sort":[
{"publish_date":{"order":"desc"}}
]
}
{
"aggs":{
"group_by_word_count":{
"terms":{
"field":"word_count"
}
},
"group_by_publish_date":{
"terms":{
"field":"publish_date"
}
}
}
}
stats:统计,min:最小,max:最大
{
"aggs":{
"grades_word_count":{
"stats":{
"field":"word_count"
}
}
}
}
四、项目简单使用
1、配置
pom文件
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
配置文件
#ES配置
elasticsearch:
hosts: 192.168.152.128
clusterName: wali
invoice.count: 5
配置类
package com.example.esdemo.config;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
/**
* ES配置
*
* @author zhanglei
* @date 2022-01-17
*/
@Configuration
public class ElasticSearchConfig {
@Value("${elasticsearch.hosts}")
private String hosts;
@Value("${elasticsearch.clusterName}")
private String clusterName;
@Bean
public TransportClient getTransportClient() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
try {
Settings settings = Settings.builder().
put("client.transport.sniff", true)
.put("cluster.name", clusterName).
build();
TransportClient client = new PreBuiltTransportClient(settings);
//分号
String[] addressArray = hosts.split(";");
if (addressArray == null) {
throw new Exception("ES服務配置异常");
}
for (String address : addressArray) {
//冒号
String[] addressParts = address.split(":");
String host = address;
int port = 9300;
if (addressParts.length == 2) {
host = addressParts[0];
port = Integer.parseInt(addressParts[1]);
}
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));
}
return client;
} catch (Exception e) {
System.out.println("ES服務配置异常");
System.exit(1);
return null;
}
}
}
2、代码使用
@Autowired
private TransportClient client;
public static final String INDEX = "people";
public static final String TYPE = "man";
@PostMapping("/man/query")
@ApiOperation(httpMethod = "POST", value = "查询")
public ResponseEntity add(@RequestParam(name = "name", required = false) String name,
@RequestParam(name = "gtAge", required = false) Integer gtAge,
@RequestParam(name = "ltAge", required = false) Integer ltAge,
@RequestParam(name = "country", required = false) String country,
@RequestParam(name = "countryQueryType", defaultValue = "1") Integer countryQueryType,
@RequestParam(name = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") String date,
@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "3") Integer pageSize) {
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
if (name != null) {
boolQuery.must(QueryBuilders.matchQuery("name", name));
}
//范围查询
if (gtAge != null || ltAge != null) {
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
if (gtAge != null && gtAge > 0) {
rangeQuery.from(gtAge);
}
if (ltAge != null && ltAge > 0) {
rangeQuery.to(ltAge);
}
boolQuery.filter(rangeQuery);
}
if (country != null) {
if (countryQueryType == 1) {
//精确查询
boolQuery.must(QueryBuilders.termQuery("country.keyword", country));
} else {
//模糊查询,(有一个分词能匹配也会返回,根据匹配度)
boolQuery.must(QueryBuilders.matchQuery("country", country));
}
}
SearchRequestBuilder builder = this.client.prepareSearch(INDEX)
.setTypes(TYPE)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(boolQuery)
.setFrom(pageNum)
.setSize(pageSize);
System.out.println(builder);
SearchResponse response = builder.get();
ArrayList<Map<String, Object>> result = new ArrayList<>();
for (SearchHit hit : response.getHits()) {
result.add(hit.getSourceAsMap());
}
return new ResponseEntity(result, HttpStatus.OK);
}