苏州建能建设科技有限公司,上海百度推广优化排名,网站建设风格,photoshop免费版一、Elasticsearch概念•以 员工文档 的形式存储为例#xff1a;一个文档代表一个员工数据。存储数据到 ElasticSearch 的行为叫做 索引 #xff0c;但在索引一个文档之前#xff0c;需要确定将文档存储在哪里。•一个 ElasticSearch 集群可以 包含多个 索引 #xff0c;相…一、Elasticsearch概念•以 员工文档 的形式存储为例一个文档代表一个员工数据。存储数据到 ElasticSearch 的行为叫做 索引 但在索引一个文档之前需要确定将文档存储在哪里。•一个 ElasticSearch 集群可以 包含多个 索引 相应的每个索引可以包含多个 类型 。 这些不同的类型存储着多个 文档 每个文档又有 多个 属性 。•类似关系 –索引-数据库 –类型-表 –文档-表中的记录 –属性-列更多详细内容见官方文档二、Elasticsearch入门2.1、安装Elasticsearch1、在虚拟机中通过Docker拉取elasticsearch镜像docker pull elasticsearch2、运行镜像并使其运行成容器9200是暴露给web端的9300是在分布式系统中各个节点交互暴露的接口docker run -e ES_JAVA_OPTS-Xms256m -Xmx256m -d -p 9200:9200 -p 9300:9300 --name my_es 5acf0e8da90b3、拷贝配置文件到宿主机必须保证容器中的ES是启动状态 从这步开始一定要跟着做不然后面使用SpringData的接口操作时会报错。详细见ARTS第三周docker cp my_es:/usr/share/elasticsearch/config/elasticsearch.yml: /usr/share/elasticsearch.yml4、停止 和 删除原来创建的容器docker stop elasticsearch
docker rm my_es5、重新执行创建容器命令重点挂载文件docker run -di --namemy_es -p 9200:9200 -p 9300:9300 -v /usr/share/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml elasticsearch6、 修改 /usr/share/elasticsearch.yml 将 transport.host: 0.0.0.0 前的 # 去掉后保存文件退出。 其作用是允许任何ip地址访问 elasticsearch 开发测试阶段可以这么做生产环境下指定具体的IP7、重启后发现重启启动失败了纯宿主机问题这与我们刚才修改的配置有关因为elasticsearch在启动的时候会进行一些检查比如最多打开的文件的个数以及虚拟内存区域数量等等8、系统调优1修改 /etc/security/limits.conf 追加内容* soft nofile 65536
* hard nofile 65536 说明nofile是单个进程允许打开的最大文件个数 soft nofile 是软限制 hard nofile是硬限制 2修改 /etc/sysctl.conf 追加内容vm.max_map_count655360说明限制一个进程可以拥有的VMA(虚拟内存区域)的数量9、重启虚拟机2.2、基本操作1、存储文档对于雇员目录我们将做如下操作每个雇员存储一个文档包含该雇员的所有信息。每个文档都将是 employee 类型 。该类型位于 索引 megacorp 内。该索引保存在我们的 Elasticsearch 集群中。实践中这非常简单尽管看起来有很多步骤我们可以通过一条命令完成所有这些动作PUT /megacorp/employee/1
{first_name : John,last_name : Smith,age : 25,about : I love to go rock climbing,interests: [ sports, music ]
}
注意路径 /megacorp/employee/1 包含了三部分的信息megacorp索引名称employee类型名称1特定雇员的ID请求体 —— JSON 文档 —— 包含了这位员工的所有详细信息他的名字叫 John Smith 今年 25 岁喜欢攀岩。很简单无需进行执行管理任务如创建一个索引或指定每个属性的数据类型之类的可以直接只索引一个文档。Elasticsearch 默认地完成其他一切因此所有必需的管理任务都在后台使用默认设置完成。进行下一步前让我们增加更多的员工信息到目录中PUT /megacorp/employee/2
{first_name : Jane,last_name : Smith,age : 32,about : I like to collect rock albums,interests: [ music ]
}PUT /megacorp/employee/3
{first_name : Douglas,last_name : Fir,age : 35,about: I like to build cabinets,interests: [ forestry ]
}
可以使用Postman软件模拟PUT请求比如存储员工id为1的文档下面会响应成功后的信息上面的其他操作同样2、检索文档目前我们已经在 Elasticsearch 中存储了一些数据 接下来就能专注于实现应用的业务需求了。第一个需求是可以检索到单个雇员的数据。这在 Elasticsearch 中很简单。简单地执行 一个 HTTP GET 请求并指定文档的地址——索引库、类型和ID。 使用这三个信息可以返回原始的 JSON 文档GET /megacorp/employee/1
返回结果包含了文档的一些元数据以及 _source 属性内容是 John Smith 雇员的原始 JSON 文档{_index : megacorp,_type : employee,_id : 1,_version : 1,found : true,_source : {first_name : John,last_name : Smith,age : 25,about : I love to go rock climbing,interests: [ sports, music ]}
}
将 HTTP 命令由 PUT 改为 GET 可以用来检索文档同样的可以使用 DELETE 命令来删除文档以及使用 HEAD 指令来检查文档是否存在。如果想更新已存在的文档只需再次 PUT 。 3、轻量搜索一个 GET 是相当简单的可以直接得到指定的文档。 现在尝试点儿稍微高级的功能比如一个简单的搜索第一个尝试的几乎是最简单的搜索了。我们使用下列请求来搜索所有雇员GET /megacorp/employee/_search
可以看到我们仍然使用索引库 megacorp 以及类型 employee但与指定一个文档 ID 不同这次使用 _search 。返回结果包括了所有三个文档放在数组 hits 中。一个搜索默认返回十条结果。{took: 6,timed_out: false,_shards: { ... },hits: {total: 3,max_score: 1,hits: [{_index: megacorp,_type: employee,_id: 3,_score: 1,_source: {first_name: Douglas,last_name: Fir,age: 35,about: I like to build cabinets,interests: [ forestry ]}},{_index: megacorp,_type: employee,_id: 1,_score: 1,_source: {first_name: John,last_name: Smith,age: 25,about: I love to go rock climbing,interests: [ sports, music ]}},{_index: megacorp,_type: employee,_id: 2,_score: 1,_source: {first_name: Jane,last_name: Smith,age: 32,about: I like to collect rock albums,interests: [ music ]}}]}
}
注意返回结果不仅告知匹配了哪些文档还包含了整个文档本身显示搜索结果给最终用户所需的全部信息。接下来尝试下搜索姓氏为 Smith 的雇员。为此我们将使用一个 高亮 搜索很容易通过命令行完成。这个方法一般涉及到一个 查询字符串 query-string 搜索因为我们通过一个URL参数来传递查询信息给搜索接口GET /megacorp/employee/_search?qlast_name:Smith
我们仍然在请求路径中使用 _search 端点并将查询本身赋值给参数 q 。返回结果给出了所有的 Smith{...hits: {total: 2,max_score: 0.30685282,hits: [{..._source: {first_name: John,last_name: Smith,age: 25,about: I love to go rock climbing,interests: [ sports, music ]}},{..._source: {first_name: Jane,last_name: Smith,age: 32,about: I like to collect rock albums,interests: [ music ]}}]}
}4、 使用查询表达式搜索Query-string 搜索通过命令非常方便地进行临时性的即席搜索 但它有自身的局限性参见 hrefhttps://www.elastic.co/guide/cn/elasticsearch/guide/current/search-lite.html轻量 搜索。Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 它支持构建更加复杂和健壮的查询。领域特定语言 DSL 指定了使用一个 JSON 请求。我们可以像这样重写之前的查询所有 Smith 的搜索 PUT /megacorp/employee/_search
{query : {match : {last_name : Smith}}
}
返回结果与之前的查询一样但还是可以看到有一些变化。其中之一是不再使用 query-string 参数而是一个请求体替代。这个请求使用 JSON 构造并使用了一个 match 查询属于查询类型之一后续将会了解。5、更复杂的搜索现在尝试下更复杂的搜索。 同样搜索姓氏为 Smith 的雇员但这次我们只需要年龄大于 30 的。查询需要稍作调整使用过滤器 filter 它支持高效地执行一个结构化查询。PUT /megacorp/employee/_search
{query : {bool: {must: {match : {last_name : smith }},filter: {range : {age : { gt : 30 } }}}}
}
目前无需太多担心语法问题后续会更详细地介绍。只需明确我们添加了一个 过滤器 用于执行一个范围查询并复用之前的 match 查询。现在结果只返回了一个雇员叫 Jane Smith32 岁。{...hits: {total: 1,max_score: 0.30685282,hits: [{..._source: {first_name: Jane,last_name: Smith,age: 32,about: I like to collect rock albums,interests: [ music ]}}]}
}
更多详细内容见官方文档三、SpringBoot整合Elasticsearch3.1、简介SpringBoot默认支持两种技术来和ES交互1、Jest默认不生效需要导入Jest工具包具体文档可去Github搜索2、SpringBoot提供的API继承SpringData的接口和ElasticsearchTempldate组件 需要指定cluster-name和cluster-nodes这种方法可能会报超时错误就是ES版本不合适 如果版本不适配 1、升级Springboot版本 2、安装对应版本ElasticSearchspring data elasticsearchspring-data-elasticsearch包版本elasticsearch(ES版本)3.2.x6.5.03.1.x6.2.23.0.x5.5.02.1.x2.4.02.0.x2.2.01.3.x1.5.23.2、JestClient操作ESmaven依赖 !-- 引入操作ElasticSearch的API --dependencygroupIdio.searchbox/groupIdartifactIdjest/artifactIdversion5.3.3/version/dependencyArticle.javaData
public class Article {JestIdprivate Integer id;private String author;private String title;private String content;}application.propertiesspring.elasticsearch.jest.urishttp://192.168.25.157:9200 测试类RunWith(SpringRunner.class)
SpringBootTest
public class Springboot11ElasticsearchApplicationTests {Autowiredprivate JestClient jestClient;Testpublic void testIndex () throws IOException {Article article new Article();article.setId(1);article.setAuthor(Yang);article.setTitle(好消息);article.setContent(Hello World);Index index new Index.Builder(article).index(ahead).type(article).build();jestClient.execute(index);}Testpublic void testSearch() throws IOException {String json {n query : {n match : {n content : hellon }n }n };Search search new Search.Builder(json).addIndex(ahead).addType(article).build();SearchResult result jestClient.execute(search);//转换为对象Article article result.getSourceAsObject(Article.class, true);//获取响应的所有信息JsonObject jsonObject result.getJsonObject();System.out.println(article);System.out.println(jsonObject);}}先执行存储文档方法没问题然后再执行检索方法结果正确更多详细信息参考官方文档3.3、SpringData的接口操作ESmaven依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-elasticsearch/artifactId/dependencyBook.javaDocument(indexName ahead, type book)
Data
public class Book { private Integer id; private String name; private String author;
}BookRepository.javapublic interface BookRepository extends ElasticsearchRepositoryBook, Integer {/*** 按照SpringData所定义的规范来创建方法底层就会帮我们实现* 某个方法对应什么操作具体可参考官方文档* 通过书名模糊查询* param name* return*/ListBook findByNameLike(String name);
}application.propertiesspring.data.elasticsearch.cluster-nameelasticsearch
spring.data.elasticsearch.cluster-nodes192.168.25.157:9300cluster-name可通过访问ip:9200获取测试类RunWith(SpringRunner.class)
SpringBootTest
public class Springboot11ElasticsearchApplicationTests {Autowiredprivate BookRepository bookRepository;Testpublic void testRepositoryIndex() {Book book new Book();book.setId(1);book.setName(西游记);book.setAuthor(吴承恩);bookRepository.index(book);}Testpublic void testRepositorySearch() {ListBook book bookRepository.findByNameLike(游);System.out.println(book);}}先执行存储方法没问题然后执行检索方法结果正确。3.4、ElasticsearchTemplate操作ES用的还是上面的环境测试类RunWith(SpringRunner.class)
SpringBootTest
public class Springboot11ElasticsearchApplicationTests {Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;Testpublic void testElasticsearchTemplateIndex() {Book book new Book();book.setId(2);book.setName(三国演义);book.setAuthor(罗贯中);IndexQuery indexQuery new IndexQueryBuilder().withObject(book).build();elasticsearchTemplate.index(indexQuery);}Testpublic void testElasticsearchTemplateSearch() {SearchQuery searchQuery new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder(name, 国)).build();ListBook books elasticsearchTemplate.queryForList(searchQuery,Book.class);System.out.println(books);}
}先执行存储文档方法成功后再执行检索方法结果正确。更多详细信息参考官方文档