赞
踩
elasticsearch与关系数据库的对应
Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。
完美解释:https://mp.weixin.qq.com/s/stC_xMP1n3aQ-0ZNAc3eQA
elasticsearch本地地址为:http://localhost:9200/
创建索引,类型,数据
使用PUT请求:访问地址/megacorp/employee/1
数据格式:
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
返回数据
{ "_index": "megacorp", "_type": "employee", "_id": "1", "_version": 1, "_seq_no": 0, "_primary_term": 1, "found": true, "_source": { "interests": [ "sports", "music" ], "first_name": "sun" } }
检索数据:
根据ID检索 GET http://localhost:9200/megacorp/employee/1 返回数据 { "_index": "megacorp", "_type": "employee", "_id": "1", "_version": 1, "_seq_no": 0, "_primary_term": 1, "found": true, "_source": { "first_name": "sun", "last_name": "sishuai", "age": 30, "about": "I like music,IT tech", "interests": [ "sports", "music" ] } }
返回指定fields _source
GET http://localhost:9200/megacorp/employee/1?_source=first_name,interests
返回所有文档_search
GET http://localhost:9200/megacorp/employee/_search
创建文档_create
如果有相同ID则创建失败,返回状态码409
PUT http://localhost:9200/megacorp/employee/1/_create
创建文档
有相同ID则更新,没有则创建
PUT http://localhost:9200/megacorp/employee/1/
删除: DELETE http://localhost:9200/megacorp/employee/5/ 返回 { "_index": "megacorp", "_type": "employee", "_id": "5", "_version": 2, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 1, "_primary_term": 1 }
指定条件检索
_search?q=last_name:Smith
添加权限控制,设置访问密码:
需要在elasticsearch.yml中添加配置,启用x-pack
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
总配置如下:
node.name: node1
cluster.name: clusters
bootstrap.system_call_filter: false
network.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: '*'
http.cors.allow-headers: Authorization,X-Requested-With,Content-Length,Content-Type
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
重启elasticsearch
在bin下运行命令:elasticsearch-setup-passwords interactive
设置所有密码
访问方式:
使用postman在authorization中type选择Basic Auth,输入刚刚设置的用户名和密码,就可以使用以前的链接操作了
elastic集群之间信息传输(传输层TLS/SSL)加密:
https://www.elastic.co/guide/en/elasticsearch/reference/6.3/configuring-tls.html#tls-active-directory
Kibana连接监控elastic文档:
https://www.elastic.co/guide/en/kibana/6.8/connect-to-elasticsearch.html
kibana.yml配置:
连接elastic,登录密码和配置一样
管理员权限
elasticsearch.username: elastic
elasticsearch.password: elastic
这个权限小
elasticsearch.username: kibana
elasticsearch.password: kibana
Logstash
可以把 Logstash 理解成流入、流出 Elasticsearch 的传送带。
支持:不同类型的数据或实施数据流经过 Logstash 写入 ES 或者从 ES 中读出写入文件或对应的实施数据流。
参考:https://blog.csdn.net/choelea/article/details/80524518
JAVA开发:https://www.elastic.co/guide/en/elasticsearch/client/index.html
分为两个Java API和Java REST Client两种:据说Java API TransportClient即将过时,所以还是用Java REST Client吧
Java REST Client:Java低级REST客户端和Java高级REST客户端两种
开发代码参考:https://blog.csdn.net/aA518189/article/details/88956889
开发:
有两种实现方式:Java Client、Spring Data
其中Spring Data 包含JPA和elasticsearch两种方式
https://www.cnblogs.com/leeSmall/p/9218779.html
个人建议:JAVA Client网上资料很多,也是官方推荐,可以使用;Spring Data因为是Spring框架集成,如果用到Spring框架可以使用,我打算尝试Spring Data
spring集成elastic认证:https://stackoverflow.com/questions/42838459/connecting-to-xpack-enabled-elasticsearch-5-x-via-spring-data-elasticsearch/46016226#46016226
spring-data-elasticsearch GitHub源码:
:https://github.com/spring-projects/spring-data-elasticsearch
官网:
有社区、博客等等
https://www.elastic.co/cn/
https://elasticsearch.cn/
关于API:
elasticsearch 自己的API,只是JSON形式的,搜索查询
用于练手elasticsearch 工具原生查询
https://www.elastic.co/guide/en/elasticsearch/reference/6.0/normalizer.html
Spring官方的关于Spring Data elasticsearch配置及使用文档,各种细节(都在超链接里),包含方法的命名等等
两个地址是一样的,一个是指定了3.1.10版本,另一个是最新版本
https://docs.spring.io/spring-data/elasticsearch/docs/3.1.10.RELEASE/reference/html/#elasticsearch.repositories
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/
JAVA开发使用的API
JAVA版本的elasticsearch内核核心6.0.1 API版本
https://static.javadoc.io/org.elasticsearch/elasticsearch/6.0.1/overview-summary.html
Spring Data elasticsearch
https://docs.spring.io/spring-data/elasticsearch/docs/current/api/
elasticserach官方提供:
Java高级REST客户端--具体查询API:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-query-builders.html
Elasticsearch客户端API:
https://www.elastic.co/guide/en/elasticsearch/client/index.html
为什么spring配置的是9300端口,而我们请求的时候用的是9200
9200作为Http协议,主要用于外部通讯
9300作为Tcp协议,jar之间就是通过tcp协议通讯
ES集群之间是通过9300进行通讯
spring-data-elasticsearch 3.1.10.RELEASE和3.0.8.RELEASE之间源码存在差异
@Bean
public TransportClient transportClient() throws UnknownHostException {
return new PreBuiltXPackTransportClient(Settings.builder()
.put("cluster.name", "clusters")
.put("xpack.security.user", "elastic:elastic")
.build())
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
本段代码中的InetSocketTransportAddress存在于3.0.8,而3.1.10不存在
[WARN ][o.e.t.OutboundHandler ] [node1] send message failed [channel:
Netty4TcpChannel{localAddress=0.0.0.0/0.0.0.0:55964, remoteAddress=/127.0.0.1:9300}]
javax.net.ssl.SSLException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[?:?]
这个报错是因为开启了xpack安全验证导致的,xpack只有30天有效期,需要的话需要续费
避免报错需要将elasticsearch.yml相关配置xpack关闭(false)
xpack.security.enabled: false
xpack.security.transport.ssl.enabled: false
首先要检查spring版本、elastic版本、以及spring data版本、还有其他各种版本
1.报错找不到org/springframework/core/ReactiveTypeDescriptor
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document
from file [D:\学习技术\shiro\shiro-example-master\shiroall\elastic-search\target\elastic-search\WEB-INF\classes\app-
elastic.xml]; nested exception is java.lang.NoClassDefFoundError: org/springframework/core/ReactiveTypeDescriptor
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.j
ava:414)
***
***
Caused by: java.lang.NoClassDefFoundError: org/springframework/core/ReactiveTypeDescriptorCaused by: java.lang.NoClassDefFoundError: org/springframework/core/ReactiveTypeDescriptor
这是由于spring版本不匹配引起的,新版的elasticsearch一般都是对spring版本要求很高,因此我把我的spring从4.X升级到5.X,问题解决
https://stackoverflow.com/questions/51588873/java-lang-abstractmethoderror-with-spring-data-elasticsearch
pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
估计可能是spring-data-elasticsearch等引起的版本不一致问题,,导致加载的时候旧版本中的spring没有相关的方法
2.java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException
升级databind
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<!--<version>2.8.7</version>-->
<version>2.9.5</version>
</dependency>
由2.8.7升级2.9.5
3.Java ElasticSearch None of the configured nodes are available
xml配置elastic的时候,cluster-name属性是必不可少的
4.报错:nested exception is org.springframework.data.mapping.PropertyReferenceException: No property firstName found for type Employee! Did you mean ‘first_Name’?
这个问题是由于属性使用自定义方法名中含有下划线,但是PO中没有xxx.first.name属性,elasticsearch对于继承
ElasticsearchRepository的user Repository方法名解析下划线代表下划线前的表示引用,后面的表示属性(可能表达不
准确),如上述它会去PO中通过方法名findByFirst_Name去查找是否存在po.first.name属性,而不是po.first_name,因
此在elastic中最好不要出现带有下划线的属性,po中最好也不要用,要驼峰命名,**下面也有解释,和JAVA解决办法**
一般来说elastic命名有规则限制都是findByxxx,getByxxx等等,并且名字直接与实体类PO有关(一般都是相同),spring data elasticsearch根据方法名称自动生成查询语句,如果属性中存在下滑线,一般要改成驼峰命名,否则无法处理;属性带下滑线,当定义成方法名后,会被认为成是对象的属性,例如 List<Employee> findByFirst_name(String name);
会被解析成Employee.first.name,而Employee对象只有first_name
参考:https://docs.spring.io/spring-data/elasticsearch/docs/3.1.10.RELEASE/reference/html/#repositories.query-methods.details
一般实现数据查询有两种JPA和spring data
JAP就是典型的JAVA提供的API进行查询,包括注解和XML方式,传统的hibernate就是JPA,里头有一套方法继承下来可以使用,注解会有@Table @Column @Entity;mybatis不是JPA,mybatis是另一套持久层框架
elasticsearch也有两种实现方式spring data JPA和spring data elasticsearch,
区别在于继承的Repository,如果是显示继承那么就是两者之一
如果没有显示继承,那么就看PO注解
5.由于版本原因查询语句变更
新版本:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
//参数firstName大小写都能查
.withFilter(QueryBuilders.matchQuery(field,value))
//参数firstName如果大写了查不到相应的数据
//.withFilter(QueryBuilders.termQuery("first_name",firstName))
.build();
历史版本:
QueryBuilder boolQueryBuilder = boolQuery().should(matchQuery("skuCode", keyword)).
should(matchQuery("name", keyword));
FilterBuilder filterBuilder = boolFilter().must(termFilter("enabled", true), termFilter("type", "SIMPLE"),
termFilter("tenantCode", "Triveni"));
NativeSearchQueryBuilder().withQuery(QueryBuilders.filteredQuery(boolQueryBuilder, filterBuilder).build();
差别在于boolFilter()和withFilter()上
Spring Data Elasticsearch集成–简单举例
pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
elastic.xml
虽然配置了elasticsearchTemplate,如果用的是elasticsearch repositories不会用到,(例子中用到了)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd "> <!-- 扫描DAO包 自动创建实现 --> <elasticsearch:repositories base-package="com.elastic.dao" /> <!-- 配置elasticsearch 连接 --> <elasticsearch:transport-client id="client" cluster-nodes="localhost:9300" cluster-name="clusters"/> <!-- spring data elasticsearch DAO 必须依赖 elasticsearchTemplate --> <bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate"> <constructor-arg name="client" ref="client" /> </bean> </beans>
Repository(例子中是dao层)
package com.elastic.dao;
import com.elastic.po.Employee;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface NameQuery extends ElasticsearchRepository<Employee, String> {
List<Employee> findByAge(String age);
}
PO
service
package com.elastic.service;
import com.elastic.po.Employee;
import java.util.List;
public interface NameQueryService {
List<Employee> findByFirstName(String firstName);
List<Employee> findByFirstNameFromQuery(String firstName);
List<Employee> findByAge(String age);
}
service-impl
package com.elastic.service.impl; import com.elastic.dao.NameQuery; import com.elastic.po.Employee; import com.elastic.service.NameQueryService; import org.elasticsearch.index.query.QueryBuilders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import static org.elasticsearch.index.query.QueryBuilders.*; @Service public class NameQueryServiceImpl implements NameQueryService { @Autowired private NameQuery nameQuery; @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Override public List<Employee> findByAge(String age) { List<Employee> emps = nameQuery.findByAge(age); return emps; } @Override public List<Employee> findByFirstName(String firstName) { List<Employee> emps = new ArrayList<Employee>(); SearchQuery searchQuery = userSearchQuery("first_name",firstName); Page<Employee> empsPage = nameQuery.search(searchQuery); if(!empsPage.isEmpty()){ emps = empsPage.getContent(); } return emps; } public List<Employee> findByFirstNameFromQuery(String firstName){ SearchQuery searchQuery = userSearchQuery("first_name",firstName); List<Employee> emps = elasticsearchTemplate.queryForList(searchQuery,Employee.class); return emps; } public SearchQuery userSearchQuery(String field,String value){ SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) //参数firstName大小写都能查 .withFilter(QueryBuilders.matchQuery(field,value)) //参数firstName如果大写了查不到相应的数据 //.withFilter(QueryBuilders.termQuery("first_name",firstName)) .build(); return searchQuery; } }
controller
package com.elastic.controller; import com.elastic.po.Employee; import com.elastic.service.NameQueryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/nameQuery") public class NameQueryController { @Autowired private NameQueryService nameQueryService; @RequestMapping("/findByFirstName.do") public List<Employee> findByFirstName(@RequestParam String firstName){ return nameQueryService.findByFirstName(firstName); } @RequestMapping("/findByAge.do") public List<Employee> findByAge(@RequestParam String age){ return nameQueryService.findByAge(age); } @RequestMapping("/findByFirstNameFromQuery.do") public List<Employee> findByFirstNameFromQuery(@RequestParam String firstName){ return nameQueryService.findByFirstNameFromQuery(firstName); } }
索引(例子):
{ "_index": "megacorp", "_type": "employee", "_id": "2", "_score": 1.0, "_source": { "first_name": "John", "last_name": "smith", "age": 19, "about": "I like qiaqia", "interests": [ "movie", "eat" ] } }, { "_index": "megacorp", "_type": "employee", "_id": "4", "_score": 1.0, "_source": { "first_name": "cc", "last_name": "smith", "age": 19, "about": "I like qiaqia", "interests": [ "movie", "eat" ] } } }
数据导入,增删改查,按score,权重进行匹配,spring data elasticsearch API
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。