在默认情况下,ES对搜索结果是按照相关性降序排序的。有时需要按照某些字段的值进行升序或者降序排序。
ES提供了sort子句可以对数据进行排序。使用sort子句一般是按照字段信息进行排序,不受相关性影响,而且打分步骤需要耗费一定的硬件资源和时间,因此默认情况下,不对文档进行打分。使用sort排序分为两种类别,一种是按照字段值的大小进行排序,另一种是按照给定地理坐标的距离远近进行排序。
按普通字段值排序
使用sort子句对字段值进行排序时需要指定排序的字段。ES默认是按照字段值进行升序排序,可以设置order参数为asc或desc,指定按照字段值进行升序或者降序排序。以下示例为搜索名称包含“北京”的旅馆,并对旅馆按照价格进行降序排列:
GET /hotel/_search
"query": {
"match": {
"title": "北京"
"sort": [
"price": {
"order": "desc"
使用sort对搜索结果排序后,在每个文档的_source信息下面多出了一个sort信息,该信息中显示了当前文档排序字段的值。另外,文档的_score值和max_score都为null,这说明在默认情况下ES查询时使用sort对结果排序是不计算分数的。也可以使用sort对搜索结果按照多个字段进行排序。例如,用户可以按照价格进行降序排列,然后再按照口碑值进行降序排列,对应的DSL如下:
GET /hotel/_search
"query": {
"match": {
"title": "北京"
"sort": [
"price": {
"order": "desc"
"praise": {
"order": "desc"
在Java客户端中对搜索结果进行排序时,可以一次或者多次调用searchSourceBuilder.sort()方法添加一个或多个排序条件。对应上面的排序DSL,Java代码如下:
@Test
public void testNormalFieldSort() throws IOException {
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(Arrays.stream("127.0.0.1:9200".split(","))
.map(host->{
String[] split = host.split(":");
String hostName = split[0];
int port = Integer.parseInt(split[1]);
return new HttpHost(hostName,port,HttpHost.DEFAULT_SCHEME_NAME);
}).filter(Objects::nonNull).toArray(HttpHost[]::new)));
SearchRequest request = new SearchRequest("hotel");
request.source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("title","北京")).sort("price", SortOrder.DESC)
.sort("praise",SortOrder.DESC));
SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
for (SearchHit hit:searchResponse.getHits()) {
System.out.println(hit.getSourceAsString()+" "+hit.getScore());
按地理距离排序
使用geo_distance查询,配合sort可以指定另一种排序规则,即按照文档坐标与指定坐标的距离对结果进行排序。使用时,需要在sort内部指定排序名称为geo_distanc,并指定目的地坐标。除了可以指定升序或者降序排列外,还可以指定排序结果中sort子句中的距离的计量单位,默认值为km即千米。在进行距离计算时,系统默认使用的算法为arc,该算法的特点是计算精准但是耗费时间较长,用户可以使用distance_type参数选择另一种计算速度快但经度略差的算法,名称为plane。如下示例使用geo_distance查询天安门5km范围内的旅馆,并按照距离由近及远进行排序:
GET /hotel/_search
"query": {
"geo_distance":{
"distance":"5km",
"location":{
"lat":39.915143,
"lon":116.4039
"sort": [
"_geo_distance": {
"location": {
"lat":39.915143,
"lon":116.4039
"order": "asc",
"unit": "km",
"distance_type": "plane"
在Java客户端中对geo_distance的搜索结果进行排序时,可以调用SortBuilders.geo DistanceSort()方法新建geo_distance查询对象的实例,然后将该实例传给searchSource Builder.sort()方法即可完成按照距离排序的要求。对应上面的排序DSL,Java代码如下:
@Test
public void testGeoSort() throws IOException {
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(Arrays.stream("127.0.0.1:9200".split(","))
.map(host->{
String[] split = host.split(":");
String hostName = split[0];
int port = Integer.parseInt(split[1]);
return new HttpHost(hostName,port,HttpHost.DEFAULT_SCHEME_NAME);
}).filter(Objects::nonNull).toArray(HttpHost[]::new)));
SearchRequest request = new SearchRequest("hotel");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.geoDistanceQuery("location").distance(5, DistanceUnit.KILOMETERS)
.point(39.915143, 116.4039));
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", 39.915143, 116.4039).point(39.915143, 116.4039).unit(DistanceUnit.KILOMETERS);
searchSourceBuilder.sort(geoDistanceSortBuilder);
SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
for (SearchHit hit:searchResponse.getHits()) {
System.out.println(hit.getSourceAsString()+" "+hit.getScore());
在实际开发过程中,往往需要先写出符合需求的查询的DSL,然后对照DSL进行Java编码,最后再通过对比两方的结果是否一致来判定程序正确与否。
在默认情况下,ES对搜索结果是按照相关性降序排序的。有时需要按照某些字段的值进行升序或者降序排序。ES提供了sort子句可以对数据进行排序。使用sort子句一般是按照字段信息进行排序,不受相关性影响,而且打分步骤需要耗费一定的硬件资源和时间,因此默认情况下,不对文档进行打分。使用sort排序分为两种类别,一种是按照字段值的大小进行排序,另一种是按照给定地理坐标的距离远近进行排序。...
:用Python编写的Web框架,用于服务所有页面。
& :异步排队服务器,用于获取和解析RSS feed。
, 和 :非关系数据库,用于存储故事,阅读故事,提要/页面获取历史以及代理站点。
:关系数据库,用于存储提要,订阅和用户帐户。
:程序员的数据库,用于组装河流的故事,存储故事ID,管理提要时间表以及NewsBlur使用的少量缓存。
:搜索数据库,用于搜索故事。 可选的。
客户端和设计
:跨浏览器兼容JavaScript代码。 IE可以毫不费力地工作。
:JavaScript的功能性编程。 必不可少。
:Web应用程序的框架。 也是必不可少的。
杂项jQuery插件:从可调整大小的布局到进度条,可排序项,日期处理,颜色,角落
文章目录前言一、cardinality(去重计数)查询1.1、依据province字段查询所有公司驻场在几个城市,即去重province后,最终有几个城市。1.1.1、RESTful 代码1.1.1.1、注意: 不适合需要精确去重场景1.1.2、java 代码二、range(范围统计)查询三、extended_stats(统计聚合)查询
ES的聚合查询和MySQL的聚合查询类型类似,但是ES的聚合查询相比于MySQL要强大的多,ES提供的统计数据的方式多种多样,这里就挑选几个常用的来示范一下,更多的内
1 使用精确查询
使用QueryBuilders.termQuery()查询时,字段的数据类型可以是keyword,也可以是text但必须指定分词策略(例如:“ik_max_word"),注意这有坑。
例如,(1)在ES中使用QueryBuilders.termQuery("name", "雷锋网")搜索字段name中含有“雷锋网”的数据;
如果name字段的数据类型是"keyword",能够搜索出”雷锋网“数据;
如果name字段的数据类型是“text”,不能搜出”雷锋网“数据;
(2)在.
已归档除非您使用的是非常老的浏览器或Node.js运行时,否则不需要此库! 常规的arr.sort()可以相同地工作,并且现在要快得多。 如果按新近度排序(最新),请。
等值排序
一个很小的(110B)实用程序,可以对日期字符串进行排序
将字符串转换为Date实例非常昂贵。 除非您确实需要一个Date实例(或者无论如何都需要一个实例),否则最好依靠字符串比较逻辑。 仅用于确定排序顺序的解析日期的浪费日子已经一去不复返了。
尽管首选ISO 8601标准(请参见 ),但您真正需要的只是YYYY-MM-DD前缀,以进行安全的LTR字符比较。
注意: MM/DD/YYYY和DD-MM-YYYY类的格式将产生错误的结果。
该模块的交付方式为:
CommonJS :
ES模块:
UMD :
$ npm install --save sort-isostring
import
var SortParser = require ( 'sort-parser' )
var sp = new SortParser (
{ format : SortParser . es
, fields : [ 'name' , 'email' ]
, strict : true
assert . deepEquals (
sp . parse ( '-email,name' )
, [ { 'email' : 'desc' } , { 'name' : 'asc' } ]
$ npm install sort-parser
$ npm test
麻省理工学院
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 查询所有数据
sourceBuilder.query(QueryBuilders.matchAllQuery());
request.source(sourceBui
Elasticsearch 是一个基于 Lucene 的搜索引擎。它的核心功能包括:全文检索、结构化搜索、分析和存储。
Elasticsearch 的源码主要由 Java 编写,使用 Maven 进行管理和构建。它的核心模块包括:
- `core`: 这是 Elasticsearch 的核心模块,包含了 Lucene 的核心功能、分布式系统相关的类和整个系统的配置。
- `search`: 这个模块提供了搜索相关的功能,包括解析查询请求、计算相关性分值、返回查询结果等。
- `index`: 这个模块提供了索引相关的功能,包括索引文档、维护索引元数据等。
- `transport`: 这个模块是 Elasticsearch 的通信模块,提供了与其他节点之间进行通信的功能。
这些模块是 Elasticsearch 的核心模块,它们之间相互协作来完成整个搜索引擎的功能。
你可以在 Elasticsearch 的 GitHub 上找到它的源码,并通过阅读代码来更好的理解 Elasticsearch 的工作原理。
需要注意的是,源码解析很需要经验和熟练技巧, 是一项需要不断研究和练习的事情。如果您不熟悉java,