ElasticSearch学习总结(基础篇,可学习,可复习) | 您所在的位置:网站首页 › 搜索引擎总结 › ElasticSearch学习总结(基础篇,可学习,可复习) |
推荐:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。。 点击跳转到网站 最近一周都在学习ElasticSearch,之前也零零散散的学过一点,这次下定决心花一周的时间将之前学的知识总结一下,顺便接着再往下学习,所以写篇博客总结一下最近一周的成果,本篇属于ElasticSearch的基础篇,后面会继续深入学习。也希望这篇拙作可以帮助到诸位大佬,如有不足之处,还望诸佬不吝赐教,倾囊相授。 ElasticSearch、简称ES,ES是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储,检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据,ES也使用Java开发使用Lucene作为其核心来实现所有索引和搜索的功能,但是他的目的是通过简单的RestFul API来隐藏Lucene的复杂性,从而让全文搜索变得简单。 ElasticSearch是一个实时分布式搜索和分析引擎,它让你以前所未有的速度处理大数据成为可能 它用于全文搜索、结构化、分析以及将这三者混合使用 维基百科使用ElasticSearch提供全文搜索并高亮关键字,以及输入实时搜索(search-asyou-type)和搜索纠错等搜索建议功能…… ElasticSearch是一个基于Apache Lucene的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进,性能最好的,功能最全的搜索引擎库 但是,Lucene只是一个库,想要使用它,你必须使用java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的 ElasticSearch也使用java开发并使用Lucene作为其核心来实现所有索引和搜索功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单! Solr简介Solr是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器,Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展、并对索引、搜索性能进行了优化! Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr索引的实现方法很简单,==用POST方法向Solr服务器发送一个描述Field及其内容的XML文档,Solr根据xml文档添加,删除,更新索引,==Solr搜索只需要发送HTTP GET请求,然后对Solr返回xml、json等格式的查询结果进行解析,组织页面布局,Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。 Solr是基于Lucene开发企业级搜索服务器,实际上就是封装Lucene Solr是一个独立的企业级搜索应用服务器,它对外提供类似与web-service的API接口,用户可以通过http请求,向搜索引擎服务器提交一定格式的文件,生成索引,也可以通过提交查找请求,并得到返回结果! ElasticSearch 和 Solr 当单纯的对已有数据进行搜索时,Solr更快!当实时建立索引时,Solr会产生IO阻塞,查询性能较差,ElasticSearch具有明显的优势随着数据量的增加,Solr的搜索效率会变得更低,而ElasticSearch却没有明显的的变化ElasticSearch vs Solr ES基本是开箱即用(解压就可以用),非常简单,Solr安装稍微复杂一点Solr利用Zookeeper进行分布式管理。而ElasticSearch自身带有分布式协调管理功能Solr支持更多格式的数据,比如JSON、XML、CSV,而ElasticSearch仅支持json文件格式Solr官方提供的功能更多,而ElasticSearch本身更注重核心功能,高级功能多有第三方插件提供,例如,图形化界面,Kibana友好支撑Solr查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用; ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索Solr是传统搜索应用的有利解决方案,但ElasticSearch更适用于新兴的实时搜索应用 6.Solr比较成熟,有一个更大,更成熟的用户,开发和贡献者社区,而ElasticSearch相对开发维护者少,更新太快,学习成本较高 ElasticSearch安装Java开发,ElasticSearch的版本和我们之后对应的java的核心jar包,版本对应,java环境正常! 2、熟悉目录 bin 启动文件 config 配置文件 log4j2 日志配置文件 jvm.options java虚拟机相关的配置 ElasticSearch ElasticSearch配置文件 默认端口9200 !跨域 lib 相关jar包 modules 功能模块 plugins 插件3、启动 ,访问9200 elasticsearch.bat 4、访问测试 安装可视化界面 es head的插件 1、下载地址https://github.com/mobz/elasticsearch-head 2、启动 npm install 安装依赖 npm run start 启动3、连接测试发现,存在跨域问题:配置es http.cors.enabled: true http.cors.allow-origin: "*"4、重启es ,再次连接 初学,可以把es当做一个数据库!(可以建立索引(库),文档(库中的数据)) 这个head我们就把它当做数据展示工具!我们后面所有的查询,Kibana 安装Kibana Kibana是一个针对ElasticSearch的开源分析及可视化平台,用来搜索,查看交互存储在ElasticSearch索引中的数据,使用Kibana,可以通过各种图表进行高级数据分析及展示,Kibana让海量数据更容易理解,基于浏览器的用户界面可以快速创建仪表板实时显示ElasticSearch查询动态,设置Kibana非常简单,无序编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动ElasticSearch索引检测。 官网:https://www.elastic.co/cn/kibana Kibana版本要和ES版本一致 启动测试 1、目录结构 2、启动 3、开发工具!(POST、curl、head、谷歌浏览器插件) 之后的所有的操作都在这里编写 4、汉化!自己修改Kibana.yml ! zh-CN 概述 集群、节点、索引、类型、文档、分片、映射是什么? elasticSearch是面向文档,关系型数据库 和 ElasticSearch 客观的对比!一切都是JSON Relational DBElasticSearch数据库(database)索引(indices)表(tables)types行(rows)documents字段(columns)fieldselasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档重女又包含多个字段(列) 物理设计: ElasticSearch在后台把每个索引划分为多个分片,每分分片可以在集群中的不同服务器间迁移 逻辑设计: 一个索引类型中,包含多个文档,比如说文档1,文档2,当我们索引一篇文档时,可以通过这样的一个顺序找到它:索引–>类型–>文档ID。通过这个组合我们就能索引到某个具体的文档,注意:ID不必是整数,实际上它是个字符串 文档 之前说ElasticSearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,ElasticSearch,文档有几个重要属性: 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key:value可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在ElasticSearch中,对于字段是非常灵活的,有时候,我们可以忽略改字段,或者动态的添加一个新的字段尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整型,因为ElasticSearch会保存字段和类型之间的映射及其他的设置,这种映射具体到每个映射的每种类型,这也是为什么在ElasticSearch中,类型有时候也称为映射类型。类型 索引(就是一个数据库) 倒排索引 什么是IK分词器 分词:即把一段中文或者别的划分成一个个的关键字,我们把搜索时会把自己的信息进行分词,会把数据库中或索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词。比如:“我爱狂神”会被分为:”我“,”爱“,”狂“,”神“,这显然是不符合要求的,所以我们需要安装中文分词器IK来解决这个问题 IK提供了两个分词算法:ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分 下载安装 1、https://github.com/medcl/elasticsearch-analysis-ik 2、下载完毕之后,直接放在ElasticSearch插件中即可! 3、重启ElasticSearch 测试分词器效果 ik__smart ik_max_word ik分词器增加自己的配置! 保存后重启ES! 一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件,它主要用于客户端和服务端交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。 基本的Rest命令说明: methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)POSTlocalhost:9200/索引名称/类型名称创建文档(随机文档id)POSTlocalhost:9200/索引名称/类型名称/文档id/_update修改文档DELETElocalhost:9200/索引名称/类型名称/文档id删除文档GETlocalhost:9200/索引名称/类型名称/文档id查询文档通过文档idPOSTlocalhost:9200/索引名称/类型名称/_search查询所有数据基础测试 1、创建一个索引 PUT /索引名/类型名/文档id {请求体}2、向索引中PUT值 3、name这个字段用不用指定类型呢,毕竟我们关系型数据库,是需要指定类型的 字符串类型 text 、keyword 数值类型 long、integer、short、byte、double、float、half、float、scaled 日期类型 date te布尔值类型 boolean 二进制类型 binary 等等…… 4、指定字段的类型(创建规则) 获取规则,可以通过get请求获取具体的信息 GET test2测试 如果自己的文档字段没有自定,那么es会给我们配置默认字段类型! 扩展:通过命令ElasticSearch索引情况! 通过get _cat/ 可以获得ElasticSearch的很多信息 修改索引 提交还是使用PUT 曾经的方法: 最新办法 删除索引 通过DELETE命令实现删除,根据你的请求来判断是删除索引还是删除文档记录! 基本操作 1、添加一条数据 PUT /wumao/user/1 { "name":"wumao", "age":21, "desc":"一顿操作猛如虎,一看工资2500", "tags":["技术宅","无聊者"] }2、获取数据 GET 3、更新操作 POST _update推荐使用这种更新方式 简单的搜索 GET wumao/user/1简单的条件查询 ,可以根据默认的映射规则,产生基本的查询! 复杂操作 搜索 select(排序、分页、高亮、精准查询!)
输出结果,不想要那么多结果!select name,desc . . . . 之后使用Java操作es,所有的方法和对象就是这里面的key! 排序 分页 数据下标还是从0开始的,和学的所有数据结构是一样的! /search/{current}/{pageSize} 布尔值查询 must (and),所有的条件都要符合 where id = 1 and name =xxx should( or ),所有的条件都要符合 where id = 1 orname =xxx must_not(not) 过滤器filter 具体的API测试 1、创建索引 2、判断文档是否存在 3、删除索引 4、创建文档 5、CRUD文档 @SpringBootTest class WumaoEsApiApplicationTests { @Autowired @Qualifier("restHighLevelClient") private RestHighLevelClient client; //测试创建索引 在java中所有的请求都是用Request PUT wumao_index @Test public void testCreateIndex() throws IOException { //1、创建索引请求 CreateIndexRequest request = new CreateIndexRequest("wumao_index"); //2、客户端执行请求 IndicesClient,请求后获取响应 CreateIndexResponse createIndexResponse = client.indices() .create(request, RequestOptions.DEFAULT); System.out.println(createIndexResponse); } //测试获取索引 @Test void testExistsIndex() throws IOException { GetIndexRequest re = new GetIndexRequest("wumao_index"); boolean exists = client.indices().exists(re,RequestOptions.DEFAULT); System.out.println(exists); } //测试删除索引 @Test void testDeleteIndex() throws IOException { DeleteIndexRequest request = new DeleteIndexRequest("wumao_index"); AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT); System.out.println(delete); } //添加文档 @Test void testAddDocument() throws IOException { //创建对象 User user = new User("五毛",3); //创建请求 IndexRequest request = new IndexRequest("wumao_index"); //设值一些规则 put /wumao_index/_doc/1 request.id("1"); request.timeout(TimeValue.timeValueSeconds(1)); request.timeout("1s"); //将我们的数据放入请求 json String string = JSON.toJSONString(user); request.source(string, XContentType.JSON); //客户端发送请求,获取响应的结果 IndexResponse index = client.index(request, RequestOptions.DEFAULT); System.out.println(index.toString()); System.out.println(index.status());//对应我们命令的返回状态 } //获取文档 @Test void testIsExists() throws IOException { //获取文档,判断是否存在 get/index/doc/1 GetRequest index = new GetRequest("wumao_index", "1"); //不获取返回的_source的上下文了 index.fetchSourceContext(new FetchSourceContext(false)); index.storedFields("_none_"); boolean exists = client.exists(index, RequestOptions.DEFAULT); System.out.println(exists); } //获取文档的信息 @Test void testGetDocument() throws IOException { GetRequest index = new GetRequest("wumao_index", "1"); GetResponse fields = client.get(index, RequestOptions.DEFAULT); System.out.println(fields.getSourceAsString()); System.out.println(fields); } //更新文档记录 @Test void testUpdateDocument() throws IOException { UpdateRequest index = new UpdateRequest("wumao_index", "1"); //设置超时时间 index.timeout(TimeValue.timeValueSeconds(1)); User user = new User("法外狂徒张三", 12); UpdateRequest doc = index.doc(JSON.toJSONString(user),XContentType.JSON); UpdateResponse update = client.update(index, RequestOptions.DEFAULT); System.out.println(update); } //删除文档记录 @Test void testDeleteDocument() throws IOException { DeleteRequest request = new DeleteRequest("wumao_index", "1"); //设置请求过期时间 request.timeout("1s"); DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT); System.out.println(delete.status()); } //特殊的,真的项目一般都是批量插入数据 @Test void testBulkRequest() throws IOException { BulkRequest bulkRequest = new BulkRequest(); bulkRequest.timeout("10s"); ArrayList userList = new ArrayList(); userList.add(new User("wumao",3)); userList.add(new User("wumao1",23)); userList.add(new User("wumao2",21)); userList.add(new User("wumao3",12)); userList.add(new User("wumao4",13)); userList.add(new User("wumao5",23)); userList.add(new User("wumao6",33)); for (int i = 0; i SearchRequest request = new SearchRequest("wumao_index"); //构建搜索条件 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //查询条件,我么可以使用QueryBuilders 工具类来实现 //QueryBuilders.termQuery 精确查询 //QueryBuilders.matchAllQuery(); 匹配所有 MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery(); TermQueryBuilder termQuery = QueryBuilders.termQuery("name", "wumao"); //查询过期时间 sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); request.source(sourceBuilder); SearchResponse search = client.search(request, RequestOptions.DEFAULT); System.out.println(JSON.toJSONString(search.getHits())); for (SearchHit hit : search.getHits().getHits()) { System.out.println(hit.getSourceAsMap()); } } //批量创建文档 @Test void testBulkDocument() throws IOException { BulkRequest bulkRequest = new BulkRequest(); //设置过期时间 bulkRequest.timeout("60s"); ArrayList userList = new ArrayList(); userList.add(new User("qinfeng",3)); userList.add(new User("qinfeng1",3)); userList.add(new User("qinfeng2",3)); userList.add(new User("qinfeng3",3)); userList.add(new User("qinfeng4",3)); userList.add(new User("qinfeng5",3)); for (int i = 0; i org.jsoup jsoup 1.14.2 public List parseJD(String keyWords) throws Exception { //获取请求 https://search.jd.com/Search?keyword=java String url = "https://search.jd.com/Search?keyword="+keyWords; //解析网页 (Jsoup返回的Document就是Document对象) Document document = Jsoup.parse(new URL(url), 30000); //所有在js中使用的方法,在这里都可以使用 Element element = document.getElementById("J_goodsList"); ArrayList list = new ArrayList(); //获取所有的li元素 Elements elements = element.getElementsByTag("li"); //这里的el就是每一个li标签 for (Element el : elements) { //关于这种图片特别多的网站,都是延时加载的 String price = el.getElementsByClass("p-price").eq(0).text(); String title = el.getElementsByClass("p-name").eq(0).text(); Content content = new Content(); content.setTitle(title); content.setPrice(price); list.add(content); } return list; }前后端分离 搜索高亮 //解析数据放入到es中 public Boolean parseContent(String keyWords) throws Exception { List contents = new HtmlParseUtil().parseJD(keyWords); //把查询到的数据放入到es中 BulkRequest request = new BulkRequest(); request.timeout("2m"); for (int i = 0; i if (pageNO //解析高亮字段 Map highlightFields = hit.getHighlightFields(); HighlightField title = highlightFields.get("title"); Map sourceAsMap = hit.getSourceAsMap();//原来的结果 //解析高亮字段,将原来的字段换为我们高亮的字段即可! if (title!=null){ Text[] fragments = title.fragments(); String n_title=""; for (Text text : fragments) { n_title += text; } sourceAsMap.put("title",n_title); //高亮字段替换掉原来的内容即可! } list.add(sourceAsMap); } return list; }本篇到这里就结束了!后续还会继续更新ElasticSearch调优、ElasticSearch集群以及面试题相关的内容, 感谢诸佬的点赞和支持。如有不足之处,还希望诸佬指出不足之处,加以修正。 再见了各位小伙伴! |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |