国外优秀的字体设计网站,温州做网站建设哪家好,免费虚拟主机管理系统,网站公告怎么做上文和大家一起初次了解了很多ES相关的基础知识#xff0c;本文的内容将会是实际企业中所需要的吗#xff0c;也是我们需要熟练应用的内容。 面对ES#xff0c;我们最多使用的就是查询#xff0c;当我负责这个业务时#xff0c;现不需要我去考虑如何创建索引#xff0c;添… 上文和大家一起初次了解了很多ES相关的基础知识本文的内容将会是实际企业中所需要的吗也是我们需要熟练应用的内容。 面对ES我们最多使用的就是查询当我负责这个业务时现不需要我去考虑如何创建索引添加文档等只需要根据复杂业务实现查询即可本文的重点也会在如何使用ES进行查询并给出很多实际案例进行补充解释和演示 本次案例演示说明所需要的数据-----------student数据信息
属性数值id001namezjhaddress中国陕西省延安市brief喜欢足球的男生age28
属性数值id002namewxxaddress中国陕西省渭南市brief喜欢zjh的女生age18 1 DSL查询语法1.1 什么是DSL1.2 查询所有1.3 全文检索1.4 精确查询1.5 复合查询1.6 搜索结果处理1.6.1 结果排序分页查询1.6.2 结果高亮 2 DSL语法对应Java代码的实现2.1 match_all2.1 核心代码梳理2.2 match与multi_match2.3 term和range2.4 boolean2.5 排序和分页 3 聚合索引3.1 初体验聚合效果buckets聚合案例3.2 优化聚合效果3.3 Metrics聚合案例3.4 DSL语法对应Java代码的实现3.5 多条件的聚合3.6 理解聚合 1 DSL查询语法
1.1 什么是DSL
就是在这个环境下查询语句有自己的语法格式要求需要我们熟练掌握。 或者你可以想一下在mysql环境下的sql语法这就是在ES环境下的DSL语法都是为了实现查询功能。
一个简化的查询模版GET /索引库名/_search
{query:{查询类型{查询条件条件值}}
}查询类型可以实现不同的查询效果下面的案例很好的解释给了大家。
1.2 查询所有
match_all查询全部的数据
GET /student/_search
{query:{match_all{}}
}1.3 全文检索
match查询利用分词器进行查询比如传入“男生”会将其分词取倒排索引库查询找到含有“男”与“生”数据即找到zjh和wxx的全部数据
这是一个模板
GET /student/_search
{query:{match{fieldtext}}
}实际案例拆分“男生”去brief字段中查找有无”男“与”生“最终找到zjh和wxx
GET /student/_search
{query:{match{biref男生}}
}升级案例现在不想指定一个字段去查找想查询所有的字段中的数据是否有匹配的
GET /student/_search
{query:{match{all跑步工资}}
}
这个all就表示会在所有字段idnameaddressbrief的值中去匹配”跑步工资“multi_match查询允许同时查询多个字段
这是一个模板
GET /student/_search
{query:{multi_match{querytext,fields[field1,field2]}}
}
实际案例找到address含有“延安”且brief含有”喜欢“的数据最终找到zjh和wxx
GET /student/_search
{query:{multi_match{query延安喜欢,fields[address,brief]}}
}需要注意的是multi_match设置的字段越多效率越慢推荐优先使用match
1.4 精确查询
当查询条件是不可分的keyword数值日期boolean等不会对其分词即为精确查询
term根据词条精确值查询range根据值范围查询
案例 当查询内容传入上海就希望匹配到含有“上海”的数据而不是含有“上”与“海”的这种数据。此乃term
当查询内容传入100-300元就希望匹配到在这个范围内的数据。此乃range 这是一个term模板
GET /student/_search
{query:{term{field{“value”“value”}}}
}
实际案例找到address含有“男生”的数据找到空数据因为必须精准为男生才能找到zjh
GET /student/_search
{query:{term{field{“brief”“男生延安”}}}
}这是一个range模板
GET /student/_search
{query:{range{field{“gte”“value”“lte”“value”}}}
}
实际案例找到年龄在10-20之间的人最终找到wxx
GET /student/_search
{query:{range{age{“gte”10“lte”20}}}
}注意gte是大于等于gt是大于
1.5 复合查询
Boolean Query 布尔查询是一个或者多个查询字句的组合。组合方式有
must : 必须匹配每个子查询与should选择性匹配子查询或must_not必须不匹配非不参与算分filter必须匹配 不参与算分
GET /student/_search
{query{“bool”{“must”[ {term{“address”“中国”} }{term{“name”“zjh”} }]should[ {term{“brief”“喜欢”} }{term{“brief”“足球”} }]“must_not”[{range{“age”{gte20} } }],“filter”[{term{“brief”“生”}}]}}
}这串代码表示 mustaddress必须含有中国 且 name必须含有zjh shouldbrief含有喜欢 或者 brief含有足球二选一 mustnot年龄大于等于20相反-----年龄小于20
这个案例仅仅告诉你如何理解must等下面介绍一个贴切的案例
查询名字包含“麦当劳”地点在北京人均消费不高于100元周一到周天营业的快餐店
1.6 搜索结果处理
1.6.1 结果排序分页查询
这是一个range模板
GET /student/_search
{query:{“查询类型”{}}sort[{fileld”value“}]
}
实际案例全部查询将结果按照年龄倒序若相等按照id升序排
GET /student/_search
{query:{match_all{}},sort[{”age“”desc“}{”id“”asc“}]“from”0“size”10}}
}es查询结果默认只显示10条数据。from0--------size:10表示从0开始显示10条数据 实际上如我们会将一批数据分成10批存在10台服务器的ES上。如果我们需要查询价格由低到高排序前100条底层执行的逻辑是每一台ES由低到高排序查出前100然后聚合10台机器的数据10*100从聚合结果1000中再找到前100的数据。 不过呢当我们执行数据读取时候一定是会扫描所有的ES节点不需要担心查询的时候会不会只查询当前服务器上es的数据是不会的。 1.6.2 结果高亮
浏览器搜索java可以看到查询结果中含有java部分高亮显示这是如何实现的 是ES帮忙做的我们只需要告诉ES需要高亮显示的字段和内容即可
GET /student/_search
{query:{“match”{“all”“中国”}“highlight”“fields” //高亮字段“address”requeire.field_match“false”//是否需要与查询字段匹配“pre_tags”em //用来标记高亮字段的前置标签“post_tags”“/em” //用来标记高亮字段的后置标签
}
2 DSL语法对应Java代码的实现
2.1 match_all RestHighLevelClient client 注意前面我已经获取了client关于代码实现可以理解为四个部分不同业务需要变动代码的部分只有2,4处Testvoid testMatchAll() throws IOException {//1.准备requestSearchRequest request new SearchRequest(student);//2.准备DSLrequest.source().query(QueryBuilders.matchAllQuery());//3.发送请求SearchResponse response client.search(request, RequestOptions.DEFAULT);//4.解析响应中的hitsSearchHits searchHits response.getHits();long value searchHits.getTotalHits().value; //获取value值参考ESSystem.out.println(value);SearchHit[] hits searchHits.getHits(); //获取文档数据for (SearchHit hit : hits) {String json hit.getSourceAsString();System.out.println(json);}}为什么解析response呢因为其全部内容如下图我们需要选出需要的即可
2.1’ 核心代码梳理
这里梳理一下上述java代码的对应关系帮助理解 source()方法中存在操作类型有查询query有结果排序sort有分页formsize等 QueryBuilders()里面有查询类型包括前面科普的精确查询term全部查询match_all复合查询bool等
2.2 match与multi_match 2.3 term和range 2.4 boolean 2.5 排序和分页 3 聚合索引
理解什么是聚合索引类似于group by的概念下图前两个常用。先看看聚合怎么用文末会有个案例更清楚的解释聚合的概念
3.1 初体验聚合效果buckets聚合案例
比如我现在需要统计酒店的品牌数量有几种则可以根据品牌数量进行聚合就会得到名为“七天酒店” 34家 “如家” 30家 “速8” 20家的返回结果 3.2 优化聚合效果
对价格在200元以内的酒店进行聚合这个案例表示query和aggs是平级。 3.3 Metrics聚合案例 也就是在Buckets聚合上再加了一层很好记住sorce字段是酒店评分注意观察下图发现多了count、min、max、avgsum。什么意思呢就是说我们对酒店评分进行聚合得到了最大值最小值平均值等等。
3.4 DSL语法对应Java代码的实现 3.5 多条件的聚合
就是同时聚合多个字段城市、星级、品牌 如何理解这个业务 前面提到的精确查询根据上海就可以查出city字段中含有”上海“的所有文档但是我们仅仅停留在粗暴的找出信息的阶段若我需要对上海这一类文档求平均价格计数等term的功能就显得捉襟见肘了。所以这里需要聚合处理。理解了业务需求在看看如何实现
1.准备request
2.准备DSL2.1 多个聚合字段
3.发出请求
4.解析结果4.1 分别处理聚合名称的数据2.1内容 4.1内容有几个集合字段就实现几次 实际上你只需要清楚一个字段的聚合实现流程那么当你写多个字段的聚合时仅仅需要重复2和4的代码那这些代码你可以封装成函数更优雅。
3.6 理解聚合
现在我们需要搜索城市是上海的数据 直接使用精确查询找到city字段含有”上海“的文档注意理解ES中文档的概念 聚合city字段对city字段进行聚合得到“上海”“北京”“深圳”的聚合结果注意只是聚合结果不是具体的文档数据。此外我可以对聚合结果进行求和求平均值等操作。