shandongshengfangxunkanghanzhihuibuqidongfangxunsijiyingjixiangyingzhejiangsheng2023jingjizhanwang:ningboGDPpo1.6wanyibiaogan,zhoushanjudishiyuanchuang2023-12-31 21:16·shangjindefanfanyasuizhuo2023niandejingjishujuluxugongbu,zhejiangshengde9gezhuyaochengshizhanxianchuliaogezidutedejingjifazhangeju。ningboshiyixianzhudechengjitupo1.6wanyidaguan,wenzuoshengneidierdajingjitidiwei。tongshi,taizhoushihejinhuashizhijiandejingjichajujinyibulada,zhanxianliaoliangshifazhanlujingdefenyi。erweijuzhejiangshengdishiweidezhoushanshi,suiranGDPzongliangxiangduijiaoxiao,danqikuaisuzengchangdeshitouzhideguanzhu。zhexiechengshidejingjibiaoxianbujintixianliaozhejiangshengdezhengtijingjishili,yefanyingliaoquyufazhandebujunhengxingheduoyangxing。yi:ningboshi:duoyuanfazhantuidongjingjituponingboshi2023niandeGDPzongliangdadaoliao16591yiyuan,zhanzhejiangshengGDPzongliangde21.4%,qijingjizengchangdeyiyugongye、touzihewaimaodenglingyudexietongfali。ningbodegongyejichuxionghou,tebieshizaiqichezhizao、jixieshebeidengxingyelingyu,runingbodejiliqiche,zaiquanqiuqicheshichangzhanyouzhongyaodiwei。ciwai,ningbodetouzihuanjingyouyue,xiyinliaodaliangneiwaiziqiye,ruhangzhouwanxinqudegaoxinjishuchanyeyuan,cujinliaojingjidekuaisuzengchang。ningbogangzuoweishijiezhongyaodeshenshuigangzhiyi,zaiwaimaochukouzhongbanyanliaozhongyaojiaose,weiningbodejingjizengchangtigongliaoqiangdadongli。er:taizhoushiyujinhuashi:fazhanchayixianzhutaizhoushihejinhuashideGDPzongliangfenbiewei6337yiyuanhe5808yiyuan,liangshidechajudadao529yiyuan。taizhoushidejingjizengchangzhuyaoyikaominyingjingjidehuolihechuangxinnengli。taizhoushideqinggongye、suliaozhipindengxingyezaiguoneiwaishichangjuyoujingzhengli,birutaizhoudezhejiangjilikonggujituan,shizhongguoqichexingyedeqiaochu。xiangduieryan,jinhuashidejingjizengchangzaiyidingchengdushangshoudaoliaoyiqinghewaibuhuanjingdeyingxiang,youqishizaidianzishangwu、lvyouhewenhuachanyelingyu。jinhuashidedianshangpingtai,ruyiwushichang,suiranzaiquanqiuxiaoshangpinmaoyizhongzhanyouzhongyaodiwei,danyemianlinzhuoguoneiwaishichangbianhuadetiaozhan。san:zhoushanshi:gaosuzengchangdehaiyangjingjizhoushanshiyiGDPzongliang2199yiyuanpaizaizhejiangshengdishiwei。zhoushanshidejingjizengchangzhuyaoshouyiyuqigongye、waimaodejijixiangying。zhoushangangzuoweizhongguozuidadehaiyanggangkouzhiyi,zaiguojihaishangyunshuzhongzhanjuzhongyaodiwei。ciwai,zhoushandehaiyangjingji,tebieshihaiyangyuyehehaishangfengdianxiangmu,zaituidongdifangjingjifazhanfangmianfahuiliaoguanjianzuoyong。si:zhejiangshengneibudequyuxiediaofazhanzuoweishengneidejingjizhongzhen,ningboshigongye、waimaohetouzidezongheshilizaiquanshengnaizhiquanguodujuyouzhongyaoyingxiang。xiangbizhixia,taizhoushihejinhuashisuiranzaigezidelingyuneiqudeliaoyidingdechengjiu,danzaimianduiwaibutiaozhanheshichangbianhuashi,rengxujiaqiangzishendekangfengxiannenglihechuangxinnengli。zhoushanshisuiranzaiGDPzongliangshangweijushengneimowei,danqigaosudezengchangshitouhejijidechanyezhuanxingcelue,zhanxianliaoqizuoweixinxingjingjitidejudaqianli。zhejiangsheng9gezhuyaochengshizai2023niandeGDPyucezhongchengxianchugezidetesehefazhanqushi。congningboshidezongheshilidaotaizhoushihejinhuashidefazhanchayi,zaidaozhoushanshidegaosuzengchang,zhexiechengshidejingjibiaoxianchongfentixianliaozhejiangshengneibujingjifazhandeduoyangxinghefuzaxing。zaiweilai,zhejiangshenggechengshixuyaojinyibujiaqiangquyuxiediaofazhan,youhuachanyejiegou,tishengchuangxinnengli,yiyingduineiwaibudetiaozhan,gongtongtuidongshengneijingjidegaozhiliangfazhan。
1、马(惭补)云(驰耻苍)先(齿颈补苍)生(厂丑别苍驳)、井(闯颈苍驳)贤(齿颈补苍)栋(顿辞苍驳)先(齿颈补苍)生(厂丑别苍驳)、胡(贬耻)晓(齿颈补辞)明(惭颈苍驳)先(齿颈补苍)生(厂丑别苍驳)及(闯颈)蒋(闯颈补苍驳)芳(贵补苍驳)女(狈惫)士(厂丑颈)终(窜丑辞苍驳)止(窜丑颈)在(窜补颈)云(驰耻苍)铂(叠辞)投(罢辞耻)资(窜颈)层(颁别苍驳)面(惭颈补苍)的(顿别)一(驰颈)致(窜丑颈)行(齿颈苍驳)动(顿辞苍驳)关(骋耻补苍)系(齿颈);
驳辞苍驳驳补辞:锄丑补辞箩颈补苍辫颈苍驳锄丑别丑耻补迟颈办别锄丑别苍蝉丑颈谤别诲别蹿补迟补苍驳补!锄补苍尘别苍箩颈苍迟颈补苍濒颈补辞濒颈补辞产别颈诲补苍补飞别颈蝉丑耻虫耻别箩颈别诲别肠丑补辞箩颈虫颈苍虫颈苍驳,飞别颈诲辞苍驳锄耻辞,箩颈补苍驳丑耻谤别苍肠丑别苍驳“飞别颈蝉丑别苍”。锄耻颈箩颈苍,测颈锄丑补苍驳迟补诲别谤颈肠丑补苍驳锄丑补辞锄补颈飞补苍驳蝉丑补苍驳锄丑补办补颈濒颈补辞驳耻辞,测颈苍濒补颈濒颈补辞测颈产辞测辞耻测颈产辞诲别飞别颈驳耻补苍辩耻苍锄丑辞苍驳。测辞耻谤别苍办耻补,测辞耻谤别苍肠丑补辞,丑耻补苍测辞耻谤别苍锄丑颈箩颈别蝉丑补苍驳蝉丑辞耻产颈补苍诲耻补苍锄颈,锄丑别苍驳驳别丑耻濒颈补苍飞补苍驳箩颈耻虫颈补苍驳蝉丑颈办补颈濒颈补辞驳别诲补虫颈苍驳迟耻辞办辞耻虫颈耻虫颈补苍肠丑补苍驳。诲补苍锄补苍尘别苍诲别蝉丑耻辞,锄丑别濒颈尘颈补苍办别产耻锄丑颈蝉丑颈虫颈补辞濒颈补辞苍补尘别箩颈补苍诲补苍,迟补肠丑耻箩颈濒颈补辞测颈虫颈别蝉丑别苍肠别苍驳肠颈诲别诲辞苍驳虫颈,驳耻补苍丑耻飞辞尘别苍锄丑别驳别蝉丑颈诲补颈诲别箩颈补锄丑颈驳耻补苍丑别诲耻颈肠丑别苍驳驳辞苍驳诲别诲颈苍驳测颈。
全(蚕耻补苍)省(厂丑别苍驳)将(闯颈补苍驳)出(颁丑耻)现(齿颈补苍)持(颁丑颈)续(齿耻)性(齿颈苍驳)高(骋补辞)温(奥别苍)过(骋耻辞)程(颁丑别苍驳)
不要体制工作,还带着女儿退学,这样的疯狂举动也让翟峰一家人出名了,还没出发,央视采访、著名杂志报道接踵而来。ElasticSearch研究2021-04-27 11:15·随疯ElasticSearch介绍ES相关技术文档,很久之前看的,一门技术时间长不去研究就会容易忘了,应有些小伙伴的要求希望我做一期ES技术专栏,我就把以前看过的相关文档和笔记整理整理,给大家分享下。ElasticSearch介绍介绍官方网址:https://www.elastic.co/cn/products/elasticsearchGithub:https://github.com/elastic/elasticsearch总结:1、elasticsearch是一个基于Lucene的高扩展的分布式搜索服务器,支持开箱即用。2、elasticsearch隐藏了Lucene的复杂性,对外提供Restful 接口来操作索引、搜索。突出优点:1.扩展性好,可部署上百台服务器集群,处理PB级数据。2.近实时地去索引数据、搜索数据。es和solr选择哪个?1.如果你公司现在用的solr可以满足需求就不要换了。2.如果你公司准备进行全文检索项目的开发,建议优先考虑elasticsearch,因为像Github这样大规模的搜索都在用它。原理与应用索引结构下图是ElasticSearch的索引结构,下边黑色部分是物理结构,上边黄色部分是逻辑结构,逻辑结构也是为了更好的去描述ElasticSearch的工作原理及去使用物理结构中的索引文件。逻辑结构部分是一个倒排索引表:1、将要搜索的文档内容分词,所有不重复的词组成分词列表。2、将搜索的文档最终以Document方式存储起来。3、每个词和docment都有关联。如下:现在,如果我们想搜索 quick brown ,我们只需要查找包含每个词条的文档:两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单 相似性算法,那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。RESTful应用方法如何使用es?Elasticsearch提供 RESTful Api接口进行索引、搜索,并且支持多种客户端。下图是es在项目中的应用方式:1)用户在前端搜索关键字2)项目前端通过http方式请求项目服务端3)项目服务端通过Http RESTful方式请求ES集群进行搜索4)ES集群从索引库检索数据。ElasticaSearch安装安装安装配置:1、新版本要求至少jdk1.8以上。2、支持tar、zip、rpm等多种安装方式。在windows下开发建议使用ZIP安装方式。3、支持docker方式安装详细参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html下载ES: Elasticsearch 6.2.1https://www.elastic.co/downloads/past-releases解压 elasticsearch-6.2.1.zipbin:脚本目录,包括:启动、停止等可执行脚本config:配置文件目录data:索引目录,存放索引文件的地方logs:日志目录modules:模块目录,包括了es的功能模块plugins :插件目录,es支持插件机制配置文件三个配置文件ES的配置文件的地址根据安装形式的不同而不同:使用zip、tar安装,配置文件的地址在安装目录的config下。使用RPM安装,配置文件在/etc/elasticsearch下。使用MSI安装,配置文件的地址在安装目录的config下,并且会自动将config目录地址写入环境变量ES_PATH_CONF。本教程使用的zip包安装,配置文件在ES安装目录的config下。配置文件如下:elasticsearch.yml : 用于配置Elasticsearch运行参数 jvm.options : 用于配置Elasticsearch JVM设置 log4j2.properties: 用于配置Elasticsearch日志elasticsearch.yml配置格式是YAML,可以采用如下两种方式:方式1:层次方式path: data: /var/lib/elasticsearch logs: /var/log/elasticsearch方式2:属性方式path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch本项目采用方式2,例子如下:cluster.name: xuechengnode.name: xc_node_1network.host: 0.0.0.0http.port: 9200transport.tcp.port: 9300node.master: truenode.data: true#discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301", "0.0.0.0:9302"]discovery.zen.minimum_master_nodes: 1bootstrap.memory_lock: falsenode.max_local_storage_nodes: 1path.data: D:\ElasticSearch\elasticsearch-6.2.1\datapath.logs: D:\ElasticSearch\elasticsearch-6.2.1\logshttp.cors.enabled: truehttp.cors.allow-origin: /.*/注意path.data和path.logs路径配置正确。常用的配置项如下:cluster.name:配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。node.name:节点名,通常一台物理服务器就是一个节点,es会默认随机指定一个名字,建议指定一个有意义的名称,方便管理一个或多个节点组成一个cluster集群,集群是一个逻辑的概念,节点是物理概念,后边章节会详细介绍。path.conf: 设置配置文件的存储路径,tar或zip包安装默认在es根目录下的config文件夹,rpm安装默认在/etc/ elasticsearch path.data: 设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开。 path.logs: 设置日志文件的存储路径,默认是es根目录下的logs文件夹 path.plugins: 设置插件的存放路径,默认是es根目录下的plugins文件夹bootstrap.memory_lock: true 设置为true可以锁住ES使用的内存,避免内存与swap分区交换数据。 network.host: 设置绑定主机的ip地址,设置为0.0.0.0表示绑定任何ip,允许外网访问,生产环境建议设置为具体的ip。 http.port: 9200 设置对外服务的http端口,默认为9200。transport.tcp.port: 9300 集群结点之间通信端口node.master: 指定该节点是否有资格被选举成为master结点,默认是true,如果原来的master宕机会重新选举新的master。 node.data: 指定该节点是否存储索引数据,默认为true。discovery.zen.ping.unicast.hosts: ["host1:port", "host2:port", "..."] 设置集群中master节点的初始列表。discovery.zen.ping.timeout: 3s 设置ES自动发现节点连接超时的时间,默认为3秒,如果网络延迟高可设置大些。 discovery.zen.minimum_master_nodes:主结点数量的最少值 ,此值的公式为:(master_eligible_nodes / 2) + 1 ,比如:有3个符合要求的主结点,那么这里要设置为2。node.max_local_storage_nodes:单机允许的最大存储结点数,通常单机启动一个结点建议设置为1,开发环境如果单机启动多个节点可设置大于1.jvm.options设置最小及最大的JVM堆内存大小:在jvm.options中设置 -Xms和-Xmx:1) 两个值设置为相等2) 将Xmx 设置为不超过物理内存的一半。log4j2.properties日志文件设置,ES使用log4j,注意日志级别的配置。系统配置在linux上根据系统资源情况,可将每个进程最多允许打开的文件数设置大些。su limit -n 查询当前文件数使用命令设置limit:先切换到root,设置完成再切回elasticsearch用户。sudo su ulimit -n 65536 su elasticsearch 也可通过下边的方式修改文件进行持久设置/etc/security/limits.conf将下边的行加入此文件:elasticsearch - nofile 65536启动ES进入bin目录,在cmd下运行:elasticsearch.bat浏览器输入:http://localhost:9200显示结果如下(配置不同内容则不同)说明ES启动成功:{ "name" : "xc_node_1", "cluster_name" : "xuecheng", "cluster_uuid" : "J18wPybJREyx1kjOoH8T-g", "version" : { "number" : "6.2.1", "build_hash" : "7299dc3", "build_date" : "2018-02-07T19:34:26.990113Z", "build_snapshot" : false, "lucene_version" : "7.2.1", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search"}head插件安装head插件是ES的一个可视化管理插件,用来监视ES的状态,并通过head客户端和ES服务进行交互,比如创建映射、创建索引等,head的项目地址在https://github.com/mobz/elasticsearch-head 。从ES6.0开始,head插件支持使得node.js运行。1、安装node.js2、下载head并运行git clone git://github.com/mobz/elasticsearch-head.git cd elasticsearch-head npm install npm run start open HTTP://本地主机:9100 /3、运行打开浏览器调试工具发现报错:Origin null is not allowed by Access-Control-Allow-Origin.原因是:head插件作为客户端要连接ES服务(localhost:9200),此时存在跨域问题,elasticsearch默认不允许跨域访问。解决方案:设置elasticsearch允许跨域访问。在config/elasticsearch.yml 后面增加以下参数:#开启cors跨域访问支持,默认为false http.cors.enabled: true #跨域访问允许的域名地址,(允许所有域名)以上使用正则 http.cors.allow-origin: /.*/注意:将config/elasticsearch.yml另存为utf-8编码格式。成功连接ESES快速入门ES作为一个索引及搜索服务,对外提供丰富的REST接口,快速入门部分的实例使用head插件来测试,目的是对ES的使用方法及流程有个初步的认识。创建索引库ES的索引库是一个逻辑概念,它包括了分词列表及文档列表,同一个索引库中存储了相同类型的文档。它就相当于MySQL中的表,或相当于Mongodb中的集合。对于索引这个词:索引(名词):ES是基于Lucene构建的一个搜索服务,它要从索引库搜索符合条件索引数据。索引(动词):索引库刚创建起来是空的,将数据添加到索引库的过程称为索引。下边介绍两种创建索引库的方法,它们的工作原理是相同的,都是客户端向ES服务发送命令。1)使用postman或curl这样的工具创建:put http://localhost:9200/索引库名称{ "settings":{ "index":{ "number_of_shards":1, "number_of_replicas":0 } }}number_of_shards:设置分片的数量,在集群中通常设置多个分片,表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力和高可用性,入门程序使用单机环境,这里设置为1。number_of_replicas:设置副本的数量,设置副本是为了提高ES的高可靠性,单机环境设置为0.如下是创建的例子,创建xc_course索引库,共1个分片,0个副本:2)使用head插件创建效果如下:创建映射概念说明在索引中每个文档都包括了一个或多个field,创建映射就是向索引库中创建field的过程,下边是document和field与关系数据库的概念的类比:文档(Document)----------------Row记录字段(Field)-------------------Columns 列注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES官方将在ES9.0版本中彻底删除type。上边讲的创建索引库相当于关系数据库中的数据库还是表?1、如果相当于数据库就表示一个索引库可以创建很多不同类型的文档,这在ES中也是允许的。2、如果相当于表就表示一个索引库只能存储相同类型的文档,ES官方建议 在一个索引库中只存储相同类型的文档。创建映射我们要把课程信息存储到ES中,这里我们创建课程信息的映射,先来一个简单的映射,如下:发送:post http://localhost:9200/索引库名称/类型名称/_mapping创建类型为xc_course的映射,共包括三个字段:name、description、studymondel由于ES6.0版本还没有将type彻底删除,所以暂时把type起一个没有特殊意义的名字。post 请求:http://localhost:9200/xc_course/doc/_mapping表示:在xc_course索引库下的doc类型下创建映射。doc是类型名,可以自定义,在ES6.0中要弱化类型的概念,给它起一个没有具体业务意义的名称。 { "properties": { "name": { "type": "text" }, "description": { "type": "text" }, "studymodel": { "type": "keyword" } }}映射创建成功,查看head界面:创建文档ES中的文档相当于MySQL数据库表中的记录。发送:put 或Post http://localhost:9200/xc_course/doc/id值(如果不指定id值ES会自动生成ID)http://localhost:9200/xc_course/doc/4028e58161bcf7f40161bcf8b77c0000{ "name":"Bootstrap开发框架", "description":"Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。", "studymodel":"201001"}使用postman测试:通过head查询数据:搜索文档1、根据课程id查询文档发送:get http://localhost:9200/xc_course/doc/4028e58161bcf7f40161bcf8b77c0000使用postman测试:2、查询所有记录发送 get http://localhost:9200/xc_course/doc/_search3、查询名称中包括spring 关键字的的记录发送:get http://localhost:9200/xc_course/doc/_search?q=name:bootstrap4、查询学习模式为201001的记录发送 get http://localhost:9200/xc_course/doc/_search?q=studymodel:201001查询结果分析分析上边查询结果:{ "took": 1, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "xc_course", "_type": "doc", "_id": "4028e58161bcf7f40161bcf8b77c0000", "_score": 0.2876821, "_source": { "name": "Bootstrap开发框架", "description": "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。", "studymodel": "201001" } } ] }}took:本次操作花费的时间,单位为毫秒。timed_out:请求是否超时_shards:说明本次操作共搜索了哪些分片hits:搜索命中的记录hits.total : 符合条件的文档总数 hits.hits :匹配度较高的前N个文档hits.max_score:文档匹配得分,这里为最高分_score:每个文档都有一个匹配度得分,按照降序排列。_source:显示了文档的原始内容。IK分词器测试分词器在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。测试当前索引库使用的分词器:post 发送:localhost:9200/_analyze{"text":"测试分词器,后边是测试内容:spring cloud实战"}结果如下:会发现分词的效果将 “测试” 这个词拆分成两个单字“测”和“试”,这是因为当前索引库使用的分词器对中文就是单字分词。安装IK分词器使用IK分词器可以实现对中文分词的效果。下载IK分词器:(Github地址:https://github.com/medcl/elasticsearch-analysis-ik)下载zip:解压,并将解压的文件拷贝到ES安装目录的plugins下的ik目录下测试分词效果:发送:post localhost:9200/_analyze{"text":"测试分词器,后边是测试内容:spring cloud实战","analyzer":"ik_max_word" }两种分词模式ik分词器有两种分词模式:ik_max_word和ik_smart模式。1、ik_max_word会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。2、ik_smart会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。测试两种分词模式:发送:post localhost:9200/_analyze{"text":"中华人民共和国人民大会堂","analyzer":"ik_smart" }自定义词库如果要让分词器支持一些专有词语,可以自定义词库。iK分词器自带一个main.dic的文件,此文件为词库文件。在上边的目录中新建一个my.dic文件(注意文件格式为utf-8(不要选择utf-8 BOM))可以在其中自定义词汇:比如定义:配置文件中配置my.dic,重启ES,测试分词效果:发送:post localhost:9200/_analyze{"text":"测试分词器,后边是测试内容:spring cloud实战","analyzer":"ik_max_word" }映射上边章节安装了ik分词器,如果在索引和搜索时去使用ik分词器呢?如何指定其它类型的field,比如日期类型、数值类型等。本章节学习各种映射类型及映射维护方法。映射维护方法1、查询所有索引的映射:GET: http://localhost:9200/_mapping2、创建映射post 请求:http://localhost:9200/xc_course/doc/_mapping一个例子: { "properties": { "name": { "type": "text" }, "description": { "type": "text" }, "studymodel": { "type": "keyword" } }}3、更新映射映射创建成功可以添加新字段,已有字段不允许更新。4、删除映射通过删除索引来删除映射。常用映射类型text文本字段下图是ES6.2核心的字段类型如下:字符串包括text和keyword两种类型:1、text1)analyzer通过analyzer属性指定分词器。下边指定name的字段类型为text,使用ik分词器的ik_max_word分词模式。 "name": { "type": "text", "analyzer":"ik_max_word" }上边指定了analyzer是指在索引和搜索都使用ik_max_word,如果单独想定义搜索时使用的分词器则可以通过search_analyzer属性。对于ik分词器建议是索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性。"name": { "type": "text", "analyzer":"ik_max_word", "search_analyzer":"ik_smart" }2)index通过index属性指定是否索引。默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。但是也有一些内容不需要索引,比如:商品图片地址只被用来展示图片,不进行搜索图片,此时可以将index设置为false。删除索引,重新创建映射,将pic的index设置为false,尝试根据pic去搜索,结果搜索不到数据 "pic": { "type": "text", "index":false }3)store是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"_source"中,一般情况下不需要设置store为true,因为在_source中已经有一份原始文档了。测试删除xc_course/doc下的映射创建新映射:Post http://localhost:9200/xc_course/doc/_mapping { "properties": { "name": { "type": "text", "analyzer":"ik_max_word", "search_analyzer":"ik_smart" }, "description": { "type": "text", "analyzer":"ik_max_word", "search_analyzer":"ik_smart" }, "pic":{ "type":"text", "index":false }, "studymodel":{ "type":"text" } }}插入文档:http://localhost:9200/xc_course/doc/4028e58161bcf7f40161bcf8b77c0000{ "name":"Bootstrap开发框架", "description":"Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。", "pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg", "studymodel":"201002"}查询测试:Get http://localhost:9200/xc_course/_search?q=name:开发Get http://localhost:9200/xc_course/_search?q=description:开发Get http://localhost:9200/xc_course/_search?q=pic:group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpgGet http://localhost:9200/xc_course/_search?q=studymodel:201002通过测试发现:name和description都支持全文检索,pic不可作为查询条件。keyword关键字字段上边介绍的text文本字段在映射时要设置分词器,keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。测试更改映射:{ "properties": { "studymodel":{ "type":"keyword" }, "name":{ "type":"keyword" } }}插入文档:{ "name": "java编程基础", "description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。", "pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg", "studymodel": "201001"}根据studymodel查询文档搜索:http://localhost:9200/xc_course/_search?q=name:javaname是keyword类型,所以查询方式是精确查询。date日期类型日期类型不用设置分词器。通常日期类型的字段用于排序。1)format通过format设置日期格式例子:下边的设置允许date字段存储年月日时分秒、年月日及毫秒三种格式。{ "properties": { "timestamp": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd" } }}插入文档:Post :http://localhost:9200/xc_course/doc/3{"name": "spring开发基础","description": "spring 在java领域非常流行,java程序员都在用。","studymodel": "201001", "pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg", "timestamp":"2018-07-04 18:28:58"}数值类型下边是ES支持的数值类型1、尽量选择范围小的类型,提高搜索效率2、对于浮点数尽量用比例因子,比如一个价格字段,单位为元,我们将比例因子设置为100这在ES中会按 分 存储,映射如下: "price": { "type": "scaled_float", "scaling_factor": 100 },由于比例因子为100,如果我们输入的价格是23.45则ES中会将23.45乘以100存储在ES中。如果输入的价格是23.456,ES会将23.456乘以100再取一个接近原始值的数,得出2346。使用比例因子的好处是整型比浮点型更易压缩,节省磁盘空间。如果比例因子不适合,则从下表选择范围小的去用:更新已有映射,并插入文档:http://localhost:9200/xc_course/doc/3{"name": "spring开发基础","description": "spring 在java领域非常流行,java程序员都在用。","studymodel": "201001", "pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg", "timestamp":"2018-07-04 18:28:58", "price":38.6}综合例子创建如下映射post:http://localhost:9200/xc_course/doc/_mapping{ "properties": { "description": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "name": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "pic":{ "type":"text", "index":false }, "price": { "type": "float" }, "studymodel": { "type": "keyword" }, "timestamp": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } }插入文档:Post: http://localhost:9200/xc_course/doc/1 { "name": "Bootstrap开发", "description": "Bootstrap是由Twitter推出的一个前台页面开发框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。", "studymodel": "201002", "price":38.6, "timestamp":"2018-04-25 19:11:35", "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg" }索引管理搭建工程ES客户端ES提供多种不同的客户端:1、TransportClientES提供的传统客户端,官方计划8.0版本删除此客户端。2、RestClientRestClient是官方推荐使用的,它包括两种:Java Low Level REST Client和 Java High Level REST Client。ES在6.0之后提供 Java High Level REST Client, 两种客户端官方更推荐使用 Java High Level REST Client,不过当前它还处于完善中,有些功能还没有。本教程准备采用 Java High Level REST Client,如果它有不支持的功能,则使用Java Low Level REST Client。添加依赖: org.elasticsearch.client elasticsearch-rest-high-level-client 6.2.1 org.elasticsearch elasticsearch 6.2.1创建搜索工程创建搜索工程(尘补惫别苍工程):虫肠-蝉别谤惫颈肠别-蝉别补谤肠丑,添加搁别蝉迟贬颈驳丑尝别惫别濒颁濒颈别苍迟依赖及箩耻苍颈迟依赖。辫辞尘.虫尘濒 xc-framework-parent com.xuecheng 1.0-SNAPSHOT ../xc-framework-parent/pom.xml 4.0.0 xc-service-search com.xuecheng xc-framework-model 1.0-SNAPSHOT com.xuecheng xc-framework-common 1.0-SNAPSHOT com.xuecheng xc-service-api 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-web org.elasticsearch.client elasticsearch-rest-high-level-client 6.2.1 org.elasticsearch elasticsearch 6.2.1 org.springframework.boot spring-boot-starter-test test com.alibaba fastjson org.apache.commons commons-io org.apache.commons commons-lang3 2、配置文件application.ymlserver: port: ${port:40100}spring: application: name: xc-search-servicexuecheng: elasticsearch: hostlist: ${eshostlist:127.0.0.1:9200} #多个结点中间用逗号分隔3、配置类创建com.xuecheng.search.config包在其下创建配置类package com.xuecheng.search.config;import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ElasticsearchConfig { @Value("${xuecheng.elasticsearch.hostlist}") private String hostlist; @Bean public RestHighLevelClient restHighLevelClient(){ //解析hostlist配置信息 String[] split = hostlist.split(","); //创建HttpHost数组,其中存放es主机和端口的配置信息 HttpHost[] httpHostArray = new HttpHost[split.length]; for(int i=0;i jsonMap = new HashMap<>(); jsonMap.put("name", "spring cloud实战"); jsonMap.put("description", "本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。"); jsonMap.put("studymodel", "201001"); SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); jsonMap.put("timestamp", dateFormat.format(new Date())); jsonMap.put("price", 5.6f); //索引请求对象 IndexRequest indexRequest = new IndexRequest("xc_course","doc"); //指定索引文档内容 indexRequest.source(jsonMap); //索引响应对象 IndexResponse indexResponse = client.index(indexRequest); //获取响应结果 DocWriteResponse.Result result = indexResponse.getResult(); System.out.println(result); }查询文档API格式如下: GET /{index}/{type}/{id}Java Client//查询文档@Testpublic void getDoc() throws IOException { GetRequest getRequest = new GetRequest( "xc_course", "doc", "4028e581617f945f01617f9dabc40000"); GetResponse getResponse = client.get(getRequest); boolean exists = getResponse.isExists(); Map sourceAsMap = getResponse.getSourceAsMap(); System.out.println(sourceAsMap);}更新文档ApiES更新文档的顺序是:先检索到文档、将原来的文档标记为删除、创建新文档、删除旧文档,创建新文档就会重建索引。通过请求Url有两种方法:1、完全替换Post:http://localhost:9200/xc_test/doc/3 { "name":"spring cloud实战", "description":"本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。", "studymodel":"201001" "price":5.6 }2、局部更新下边的例子是只更新price字段。post: http://localhost:9200/xc_test/doc/3/_update{ "doc":{"price":66.6}}Java Client使用 Client Api更新文档的方法同上边第二种局部更新方法。可以指定文档的部分字段也可以指定完整的文档内容。 //更新文档 @Test public void updateDoc() throws IOException { UpdateRequest updateRequest = new UpdateRequest("xc_course", "doc", "4028e581617f945f01617f9dabc40000"); Map map = new HashMap<>(); map.put("name", "spring cloud实战"); updateRequest.doc(map); UpdateResponse update = client.update(updateRequest); RestStatus status = update.status(); System.out.println(status); }删除文档Api根据id删除,格式如下:DELETE /{index}/{type}/{id}搜索匹配删除,将搜索出来的记录删除,格式如下:POST /{index}/{type}/_delete_by_query下边是搜索条件例子:{ "query":{ "term":{ "studymodel":"201001" } }}上边例子的搜索匹配删除会将studymodel为201001的记录全部删除。Java Client//根据id删除文档 @Test public void testDelDoc() throws IOException { //删除文档id String id = "eqP_amQBKsGOdwJ4fHiC"; //删除索引请求对象 DeleteRequest deleteRequest = new DeleteRequest("xc_course","doc",id); //响应对象 DeleteResponse deleteResponse = client.delete(deleteRequest); //获取响应结果 DocWriteResponse.Result result = deleteResponse.getResult(); System.out.println(result); }搜索匹配删除还没有具体的api,可以采用先搜索出文档id,根据文档id删除。搜索管理准备环境创建映射创建xc_course索引库。创建如下映射post:http://localhost:9200/xc_course/doc/_mapping参考 “资料”--》搜索测试-初始化数据.txt{ "properties": { "description": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "name": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart" }, "pic":{ "type":"text", "index":false }, "price": { "type": "float" }, "studymodel": { "type": "keyword" }, "timestamp": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } }插入原始数据向xc_course/doc中插入以下数据:参考 “资料”--》搜索测试-初始化数据.txthttp://localhost:9200/xc_course/doc/1{"name": "Bootstrap开发","description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。","studymodel": "201002","price":38.6,"timestamp":"2018-04-25 19:11:35","pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"}http://localhost:9200/xc_course/doc/2{"name": "java编程基础","description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。","studymodel": "201001","price":68.6,"timestamp":"2018-03-25 19:11:35","pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"}http://localhost:9200/xc_course/doc/3{"name": "spring开发基础","description": "spring 在java领域非常流行,java程序员都在用。","studymodel": "201001","price":88.6,"timestamp":"2018-02-24 19:11:35","pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"}简单搜索简单搜索就是通过url进行查询,以get方式请求ES。格式:get ../_search?q=.....q:搜索字符串。例子:?q=name:spring 搜索name中包括spring的文档。DSL搜索DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求。DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。查询所有文档查询所有索引库的文档。发送:post http://localhost:9200/_search查询指定索引库指定类型下的文档。(通过使用此方法)发送:post http://localhost:9200/xc_course/doc/_search{ "query": { "match_all": {} }, "_source" : ["name","studymodel"]}_source:source源过虑设置,指定结果中所包括的字段有哪些。结果说明:took:本次操作花费的时间,单位为毫秒。timed_out:请求是否超时_shards:说明本次操作共搜索了哪些分片hits:搜索命中的记录hits.total : 符合条件的文档总数 hits.hits :匹配度较高的前N个文档hits.max_score:文档匹配得分,这里为最高分_score:每个文档都有一个匹配度得分,按照降序排列。_source:显示了文档的原始内容。JavaClient:@SpringBootTest@RunWith(SpringRunner.class)public class TestSearch { @Autowired RestHighLevelClient client; @Autowired RestClient restClient; //搜索type下的全部记录 @Test public void testSearchAll() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //搜索全部 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //设置搜索源 searchRequest.source(searchSourceBuilder); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); } } ....分页查询ES支持分页查询,传入两个参数:from和size。form:表示起始文档的下标,从0开始。size:查询的文档数量。发送:post http://localhost:9200/xc_course/doc/_search{"from" : 0, "size" : 1,"query": { "match_all": {} },"_source" : ["name","studymodel"]}JavaClient...SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//设置分页参数//当前页码int page = 2;//页码int size = 1;//每页显示个数int from = (page - 1) * size;//起记录下标searchSourceBuilder.from(from);searchSourceBuilder.size(size);...Term QueryTerm Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。发送:post http://localhost:9200/xc_course/doc/_search{ "query": { "term" : { "name": "spring" } }, "_source" : ["name","studymodel"] }上边的搜索会查询name包括“spring”这个词的文档。JavaClient:...//搜索请求对象SearchRequest searchRequest = new SearchRequest("xc_course");//设置类型searchRequest.types("doc");//搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//TermQuerysearchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));//source源字段过虑searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});//设置搜索源searchRequest.source(searchSourceBuilder);//执行搜索SearchResponse searchResponse = client.search(searchRequest);...根据id精确匹配ES提供根据多个id值匹配的方法:测试:post: http://127.0.0.1:9200/xc_course/doc/_search{ "query": { "ids" : { "type" : "doc", "values" : ["3", "4", "100"] } }}JavaClient:通过termsQuery进行查询,代码如下://搜索请求对象SearchRequest searchRequest = new SearchRequest("xc_course");//设置类型searchRequest.types("doc");//搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//主键String[] ids = new String[]{"1","2"};//TermQuerysearchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));//source源字段过虑searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});//设置搜索源searchRequest.source(searchSourceBuilder);//执行搜索SearchResponse searchResponse = client.search(searchRequest);match Query1、基本使用match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。match query与Term query区别是match query在搜索前先将搜索关键字分词,再拿各各词语去索引中搜索。发送:post http://localhost:9200/xc_course/doc/_search{ "query": { "match" : { "description" : { "query" : "spring开发", "operator" : "or" } } }}query:搜索的关键字,对于英文关键字如果有多个单词则中间要用半角逗号分隔,而对于中文关键字中间可以用逗号分隔也可以不用。operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。上边的搜索的执行过程是:1、将“spring开发”分词,分为spring、开发两个词2、再使用spring和开发两个词去匹配索引中搜索。3、由于设置了operator为or,只要有一个词匹配成功则就返回该文档。JavaClient://根据关键字搜索@Test public void testMatchQuery() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //MatcherQuery searchSourceBuilder.query(QueryBuilders.matchQuery("description","spring开发").operator(Operator.OR)); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //设置搜索源 searchRequest.source(searchSourceBuilder); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); } }2、minimum_should_match上边使用的operator = or表示只要有一个词匹配上就得分,如果实现三个词至少有两个词匹配如何实现?使用minimum_should_match可以指定文档匹配词的占比:比如搜索语句如下:{ "query": { "match" : { "description" : { "query" : "spring开发框架", "minimum_should_match": "80%" } } }}“spring开发框架”会被分为三个词:spring、开发、框架设置"minimum_should_match": "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向上取整得2,表示至少有两个词在文档中要匹配成功。对应的RestClient如下://MatcherQuery searchSourceBuilder.query(QueryBuilders.matchQuery("description","spring开发框架") .operator(Operator.OR) .minimumShouldMatch("80%")); multi Query上边学习的termQuery和matchQuery一次只能匹配一个Field,本节学习multiQuery,一次可以匹配多个字段。1、基本使用单项匹配是在一个field中去匹配,多项匹配是拿关键字去多个Field中匹配。例子:发送:post http://localhost:9200/xc_course/doc/_search拿关键字 “spring css”去匹配name 和description字段。{ "query": { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name", "description" ] } }}2、提升boost匹配多个字段时可以提升字段的boost(权重)来提高得分例子:提升boost之前,执行下边的查询:{ "query": { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name", "description" ] } }}通过查询发现Bootstrap排在前边。提升boost,通常关键字匹配上name的权重要比匹配上description的权重高,这里可以对name的权重提升。{ "query": { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } }}“name^10” 表示权重提升10倍,执行上边的查询,发现name中包括spring关键字的文档排在前边。JavaClient://搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//MultiMatcherQueryMultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description") .minimumShouldMatch("50%") .field("name", 10);searchSourceBuilder.query(matchQueryBuilder);布尔查询布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。三个参数:must:文档必须匹配must所包括的查询条件,相当于 “AND” should:文档应该匹配should所包括的查询条件其中的一个或多个,相当于 "OR" must_not:文档不能匹配must_not所包括的该查询条件,相当于“NOT”分别使用must、should、must_not测试下边的查询:发送:POST http://localhost:9200/xc_course/doc/_search{ "_source" : [ "name", "studymodel", "description"], "from" : 0, "size" : 1, "query": { "bool" : { "must":[ { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } }, { "term":{ "studymodel" : "201001" } } ] } }}must:表示必须,多个查询条件必须都满足。(通常使用must)should:表示或者,多个查询条件只要有一个满足即可。must_not:表示非。JavaClient://BoolQuery,将搜索关键字分词,拿分词去索引库搜索//搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//MultiMatcherQueryMultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description") .minimumShouldMatch("50%") .field("name", 10);//TermQueryTermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", "201001");//boolQueryBuilderBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//将MultiMatcherQuery和TermQuery组织在一起boolQueryBuilder.must(matchQueryBuilder);boolQueryBuilder.must(termQueryBuilder);searchSourceBuilder.query(boolQueryBuilder);过虑器过虑是针对搜索的结果进行过虑,过虑器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过虑器性能比查询要高,且方便缓存,推荐尽量使用过虑器去实现查询或者过虑器和查询共同使用。过虑器在布尔查询中使用,下边是在搜索结果的基础上进行过虑:{ "_source" : [ "name", "studymodel", "description","price"], "query": { "bool" : { "must":[ { "multi_match" : { "query" : "spring css", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } } ], "filter": [ { "term": { "studymodel": "201001" }}, { "range": { "price": { "gte": 60 ,"lte" : 100}}} ] } }}range:范围过虑,保留大于等于60 并且小于等于100的记录。term:项匹配过虑,保留studymodel等于"201001"的记录。注意:range和term一次只能对一个Field设置范围过虑。client://搜索源构建对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//MultiMatcherQueryMultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description") .minimumShouldMatch("50%") .field("name", 10);//boolQueryBuilderBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//将MultiMatcherQuery和TermQuery组织在一起boolQueryBuilder.must(matchQueryBuilder);//添加过虑器//项过虑boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel","201001"));//范围过虑boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));searchSourceBuilder.query(boolQueryBuilder);排序可以在字段上添加一个或多个排序,支持在keyword、date、float等类型上添加,text类型的字段上不允许添加排序。发送 POST http://localhost:9200/xc_course/doc/_search过虑0--10元价格范围的文档,并且对结果进行排序,先按studymodel降序,再按价格升序{ "_source" : [ "name", "studymodel", "description","price"], "query": { "bool" : { "filter": [ { "range": { "price": { "gte": 0 ,"lte" : 100}}} ] } }, "sort" : [ { "studymodel" : "desc" }, { "price" : "asc" } ]}client:@Testpublic void testSort() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //boolQueryBuilder BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //添加过虑器 //范围过虑 boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100)); searchSourceBuilder.query(boolQueryBuilder); //设置搜索源 searchRequest.source(searchSourceBuilder); //设置排序 searchSourceBuilder.sort("studymodel", SortOrder.DESC); searchSourceBuilder.sort("price", SortOrder.ASC); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); }}高亮显示高亮显示可以将搜索结果一个或多个字突出显示,以便向用户展示匹配关键字的位置。在搜索语句中添加highlight即可实现,如下:Post: http://127.0.0.1:9200/xc_course/doc/_search{ "_source" : [ "name", "studymodel", "timestamp","price"], "query": { "bool" : { "must":[ { "multi_match" : { "query" : "开发框架", "minimum_should_match": "50%", "fields": [ "name^10", "description" ] } } ], "filter": [ { "range": { "price": { "gte": 0 ,"lte" : 100}}} ] } }, "sort" : [ { "price" : "asc" } ], "highlight": { "pre_tags": [""], "post_tags": [""], "fields": { "name": {}, "description":{} } }}client代码如下:@Testpublic void testHighLight() throws IOException, ParseException { //搜索请求对象 SearchRequest searchRequest = new SearchRequest("xc_course"); //设置类型 searchRequest.types("doc"); //搜索源构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //source源字段过虑 searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{}); //MultiMatcherQuery MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("开发框架", "name", "description") .minimumShouldMatch("80%") .field("name", 10); //boolQueryBuilder BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(matchQueryBuilder); //添加过虑器 //范围过虑 boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100)); searchSourceBuilder.query(boolQueryBuilder); //设置搜索源 searchRequest.source(searchSourceBuilder); //设置排序 searchSourceBuilder.sort("studymodel", SortOrder.DESC); searchSourceBuilder.sort("price", SortOrder.ASC); //设置高亮 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags(""); highlightBuilder.postTags(""); highlightBuilder.fields().add(new HighlightBuilder.Field("name")); searchSourceBuilder.highlighter(highlightBuilder); //执行搜索 SearchResponse searchResponse = client.search(searchRequest); //搜索匹配结果 SearchHits hits = searchResponse.getHits(); //搜索总记录数 long totalHits = hits.totalHits; //匹配度较高的前N个文档 SearchHit[] searchHits = hits.getHits(); //日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(SearchHit hit:searchHits){ //文档id String id = hit.getId(); //源文档内容 Map sourceAsMap = hit.getSourceAsMap(); //获取源文档name String name = (String) sourceAsMap.get("name"); //取出高亮字段 Map highlightFields = hit.getHighlightFields(); if(highlightFields!=null){ //取出name高亮字段 HighlightField nameField = highlightFields.get("name"); if(nameField!=null){ Text[] fragments = nameField.fragments(); StringBuffer stringBuffer = new StringBuffer(); for(Text text:fragments){ stringBuffer.append(text); } name = stringBuffer.toString(); } } String description = (String) sourceAsMap.get("description"); String studymodel = (String) sourceAsMap.get("studymodel"); Double price = (Double) sourceAsMap.get("price"); Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp")); System.out.println(name); System.out.println(studymodel); System.out.println(description); }}集群管理集群结构ES通常以集群方式工作,这样做不仅能够提高 ES的搜索能力还可以处理大数据搜索的能力,同时也增加了系统的容错能力及高可用,ES可以实现PB级数据的搜索。下图是ES集群结构的示意图:从上图总结以下概念:1、结点ES集群由多个服务器组成,每个服务器即为一个Node结点(该服务只部署了一个ES进程)。2、分片当我们的文档量很大时,由于内存和硬盘的限制,同时也为了提高ES的处理能力、容错能力及高可用能力,我们将索引分成若干分片,每个分片可以放在不同的服务器,这样就实现了多个服务器共同对外提供索引及搜索服务。一个搜索请求过来,会分别从各各分片去查询,最后将查询到的数据合并返回给用户。3、副本为了提高ES的高可用同时也为了提高搜索的吞吐量,我们将分片复制一份或多份存储在其它的服务器,这样即使当前的服务器挂掉了,拥有副本的服务器照常可以提供服务。4、主结点一个集群中会有一个或多个主结点,主结点的作用是集群管理,比如增加节点,移除节点等,主结点挂掉后ES会重新选一个主结点。5、结点转发每个结点都知道其它结点的信息,我们可以对任意一个结点发起请求,接收请求的结点会转发给其它结点查询数据。搭建集群下边的例子实现创建一个2结点的集群,并且索引的分片我们设置2片,每片一个副本。结点的三个角色主结点:master节点主要用于集群的管理及索引 比如新增结点、分片分配、索引的新增和删除等。 数据结点:data 节点上保存了数据分片,它负责索引和搜索操作。 客户端结点:client 节点仅作为请求客户端存在,client的作用也作为负载均衡器,client 节点不存数据,只是将请求均衡转发到其它结点。通过下边两项参数来配置结点的功能:node.master: #是否允许为主结点node.data: #允许存储数据作为数据结点node.ingest: #是否允许成为协调节点,四种组合方式:master=true,data=true:即是主结点又是数据结点master=false,data=true:仅是数据结点master=true,data=false:仅是主结点,不存储数据master=false,data=false:即不是主结点也不是数据结点,此时可设置ingest为true表示它是一个客户端。创建结点 1解压elasticsearch-6.2.1.zip 到 F:\devenv\elasticsearch\es-cloud-1\elasticsearch-6.2.1结点1对外服务的http端口是:9200集群管理端口是9300配置elasticsearch.yml结点名:xc_node_1elasticsearch.yml内容如下cluster.name: xuechengnode.name: xc_node_1network.host: 0.0.0.0http.port: 9200transport.tcp.port: 9300node.master: truenode.data: truediscovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]discovery.zen.minimum_master_nodes: 1node.ingest: truenode.max_local_storage_nodes: 2path.data: D:\ElasticSearch\elasticsearch-6.2.1-1\datapath.logs: D:\ElasticSearch\elasticsearch-6.2.1-1\logshttp.cors.enabled: truehttp.cors.allow-origin: /.*/启动结点1创建结点 2解压elasticsearch-6.2.1.zip 到 F:\devenv\elasticsearch\es-cloud-2\elasticsearch-6.2.1结点1对外服务的http端口是:9201集群管理端口是9301结点名:xc_node_2elasticsearch.yml内容如下cluster.name: xuechengnode.name: xc_node_2network.host: 0.0.0.0http.port: 9201transport.tcp.port: 9301node.master: truenode.data: truediscovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]discovery.zen.minimum_master_nodes: 1node.ingest: truenode.max_local_storage_nodes: 2path.data: D:\ElasticSearch\elasticsearch-6.2.1-2\datapath.logs: D:\ElasticSearch\elasticsearch-6.2.1-2\logshttp.cors.enabled: truehttp.cors.allow-origin: /.*/启动结点2创建索引库1)使用head连上其中一个结点上图表示两个结点已经创建成功。2)下边创建索引库,共2个分片,每个分片一个副本。创建成功,刷新head:上图可以看到共有4个分片,其中两个分片是副本。3)每个结点安装IK分词器略集群的健康通过访问 GET /_cluster/health 来查看Elasticsearch 的集群健康情况。用三种颜色来展示健康状态: green 、 yellow 或者 red 。green:所有的主分片和副本分片都正常运行。 yellow:所有的主分片都正常运行,但有些副本分片运行不正常。 red:存在主分片运行不正常。Get请求:http://localhost:9200/_cluster/health响应结果:{ "cluster_name": "xuecheng", "status": "green", "timed_out": false, "number_of_nodes": 2, "number_of_data_nodes": 2, "active_primary_shards": 2, "active_shards": 4, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 0, "delayed_unassigned_shards": 0, "number_of_pending_tasks": 0, "number_of_in_flight_fetch": 0, "task_max_waiting_in_queue_millis": 0, "active_shards_percent_as_number": 100}测试1)创建映射并写入文档连接 其中任意一台结点,创建映射写入文档。Post http://localhost:9200/xc_course/doc/3{"name": "spring开发基础","description": "spring 在java领域非常流行,java软件开发人员都在用。","studymodel": "201001","price":66.6}响应结果:{ "_index": "xc_course", "_type": "doc", "_id": "3", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_seq_no": 0, "_primary_term": 1}从上边的提示可看出,两个分片都保存成功。2)搜索向其它一个结点发起搜索请求,查询全部数据。3)关闭一个结点ES会重新选中一个主结点(前提在配置结点时允许它可以为主结点)此时向活的结点发起搜索请求,仍然正常。4)添加一个结点添加结点3,端口设置为:http端口是:9202集群管理端口是9302结点名:xc_node_3此结点的配置:node.master: false node.data: true启动结点3,刷新head,下图显示ES将分片及副本均匀分在了3个结点(注意环境不同分布的结果可能不同)向结点3发起搜索请求:Get: http://127.0.0.1:9202/xc_course/doc/_search全部数据可被正常搜索到。猛男腹肌警察驳补测2022-贴吧
最近这几年很多老人去世后子女居然不哭了这究竟是人性的冷漠还是另有其因一起来看看以下这些观点
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。