Mixed query
# What is a mixed query?
To put it simply, half of them use EE grammar and half use RestHighLevelClient grammar, which is similar to "oil-electricity hybrid". I believe you will love this "oil-electricity hybrid" mode because it combines the advantages of the two modes!
# Why are there mixed queries?
Because EE has not yet achieved 100% coverage of ResthighevelClient's functions, after more than a year's development, we have covered about 90% of ResthighevelClient's API and 99.9% of its core high-frequency usage functions, so it is inevitable that EE cannot meet a certain special demand in individual scenarios. At this time, redeveloping the EE framework or directly submitting the requirement to the EE author can't meet the developer's requirements in time, and some requirements may be tight for the product manager, so at this time, you can solve the dilemma through mixed query.
# What are the advantages of using mixed queries and using native queries directly?
The biggest advantage of hybrid car compared with pure gasoline car is fuel economy. In fact, so is hybrid query, which can save a lot of code than using native query directly, and is simpler than using native query directly. It has both the flexible characteristics of native grammar and the low code advantage of EE. In fact, users who have used SpringData-Es know that it is the originator of hybrid query, but shine on you is better than blue. We are late-comers. Please continue to "read on" for those who don't believe it!
# How to use mixed queries?
When I didn't provide this document, although I provided the API and brief introduction of mixed query, many people didn't know about this function, let alone how to use it, so here I will show you how to use mixed query with a specific case for your reference. Don't worry about the space, it's actually very, very simple, but my tutorial is written in detail.
background
The user "Xiangyang" WeChat gave me feedback, saying that at present, EE does not support the sorting of queries according to the location from near to far. In the actual development, this scenario can be applied to "when a passenger places an order, it is required to give priority to the driver closest to me within 3 kilometers around". Then the passenger is a beautiful woman, worried about her own safety, and adds a few more requirements, such as the driver must be a woman, the driving experience is more than 3 years, the business car, etc. ...
Take the taxi scene above as an example. Let's see how to query with EE. The above query can be divided into two parts.
-regular inquiry supported by ee: if the driver's gender is female within 3 kilometers around, inquire about driving experience > =3 years. ... -Unconventional query not supported by EE: Sort according to complex sorting rules (it was not supported when writing this document, but it is now supported, but this is not important. This article is only to demonstrate the use of mixed queries)
For the supporting part, we can call EE directly, and EE will build a SearchSourceBuilder first.
//Assume that the longitude and latitude of the passenger's position are 31.256224D, 121.462311D
LambdaEsQueryWrapper<Driver> wrapper = new LambdaEsQueryWrapper<>();
wrapper.geoDistance(Driver::getLocation, 3.0, DistanceUnit.KILOMETERS, new GeoPoint(31.256224D, 121.462311D))
. eq(Driver::getGender, "female")
.ge(Driver::getDriverAge,3)
. eq(Driver::getCarModel, "commercial vehicle");
SearchSourceBuilder searchSourceBuilder = driverMapper.getSearchSourceBuilder(wrapper);
2
3
4
5
6
7
For unsupported statements, you can continue to encapsulate them with RestHighLevelClient syntax. After encapsulation, you can directly call the mixed query interface provided by EE to complete the whole query.
//The searchSourceBuilder here is built from the EE above, and we continue to append sorting parameters to it.
searchSourceBuilder.sort(
new GeoDistanceSortBuilder("location", 31.256224D, 121.462311D)
.order(SortOrder.DESC)
.unit(DistanceUnit.KILOMETERS)
.geoDistance(GeoDistance.ARC)
);
wrapper.setSearchSourceBuilder(searchSourceBuilder);
List<Driver> drivers = driverMapper.selectList(wrapper);
2
3
4
5
6
7
8
9
In this way, you can not only enjoy the basic query generated by EE, but also complete the functions that EE doesn't support yet, and you can achieve your goal only with a little code (compared with direct RestHighLevelClient, you can still save a lot of code), which is similar to a compromise scheme-hybrid electric vehicle, which is not fully developed at present.
Of course, if you are not used to using this mode, you can still use the native query directly, so you can use EE without any worries. We have thought of all kinds of solutions and retreat for you, and have no worries after sale! If you agree with this model, you might as well give us a star. In order to make EE users happy, the author's bad old man can be described as painstaking!
# Several Correct Use Postures of Mixed Query
although there are many cases below, they are very simple to use, just because my tutorial is detailed, so don't be afraid of the readers.
/**
* Correct use of mixed queries Posture 1: The functions provided by EE do not support some over-fine-grained functions, and all query conditions are constructed by native syntax, only using the data parsing functions provided by EE.
*/
@Test
public void testMix1() {
//resthighevelclient native grammar
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchSourceBuilder. Query (QueryBuilders. Match Query ("content", "push *"). *").minimumShouldMatch("80%% "));
//Only use EE to query and parse data.
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.setSearchSourceBuilder(searchSourceBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}
/**
* Correct use posture of mixed query 2: Everything else can be supported, but only the sorter does not. In this case, the SortBuilder of the required sorter can be constructed only according to ES native grammar, and the others can be completed by EE.
*/
@Test
public void testMix2() {
//syntax that ee satisfies.
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Wrapper.eq(Document::getTitle, "old man")
. match(Document::getContent, "push *");
//resthighevelclient native grammar
Script script = new Script("doc['star_num'].value");
ScriptSortBuilder scriptSortBuilder = SortBuilders.scriptSort(script,ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
//Query and parse data with EE
wrapper.sort(scriptSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}
/**
* Correct use posture of mixed query 3: Other functions can be supported, but non-query parameters need to be added to SearchSourceBuilder.
*/
@Test
public void testMix3() {
//syntax that ee satisfies.
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Wrapper.eq(Document::getTitle, "old man")
. match(Document::getContent, "push *");
SearchSourceBuilder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
//Append or set some parameters that SearchSourceBuilder supports but EE doesn't support for the time being. It is not recommended to append the query parameter, because if you append the query parameter, it will directly overwrite the query that EE has generated for you, and the query set last will prevail.
searchSourceBuilder.timeout(TimeValue.timeValueSeconds(3L));
wrapper.setSearchSourceBuilder(searchSourceBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}
/**
* Most basic queries can be used in query conditions, but if the aggregation function provided by EE can't meet the demand, you need to customize the aggregator.
*/
@Test
public void textMix4() {
//syntax that ee satisfies.
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Wrapper.eq(Document::getTitle, "old man")
. match(Document::getContent, "push *");
SearchSourceBuilder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
//resthighevelclient native grammar
AggregationBuilder aggregation = AggregationBuilders.terms("titleAgg")
.field("title");
searchSourceBuilder.aggregation(aggregation);
wrapper.setSearchSourceBuilder(searchSourceBuilder);
SearchResponse searchResponse = documentMapper.search(wrapper);
//The information after TODO Aggregation is dynamic and cannot be parsed by the framework. Users need to parse it from the bucket by themselves according to the aggregator type. Please refer to the official aggregation parsing document of RestHighLevelClient.
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Use posture of mixed query error
Tell a story. Once upon a time, there was a lazy man who was too lazy to be stingy. One day, there was a diligent old man who saw that he had no fixed place and promised to build him a mansion to make him live more comfortably. The old man repaired the house and told him where the door was, but the lazy man just wouldn't listen. I had to climb through the skylight and thought it was cool. As a result, I accidentally fell down and broke my leg. I went to the court to tell the old man that there was something wrong with the house he had repaired, and I went to the street to pull banners and scold the old man for being a bad old man. ...
I have listed all the mixed query usage schemes supported by EE in the correct usage posture above, which can cover any usage scenario. Please don't make up your imagination out of thin air and then write it in the way you think it's okay. You don't take a look at the documents and source codes, but you still have to use the YY scheme yourself. Finally, you come to the Q&A group and ask me why I don't support it. You also say that there are holes in the code, which makes the comrades in the code protect the country from danger. ...
Here are two typical unsupported scenarios:
/**
* Unsupported mixed query 1: Append coverage problem
*/
@Test
public void textNotSupportMix() {
//syntax that ee satisfies.
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Wrapper.eq(Document::getTitle, "old man")
. match(Document::getContent, "push *");
SearchSourceBuilder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
//The user wants to add some personalized query parameters on the basis of the above, but in fact, when the query is executed at this time, the query condition is only the last set title= Lao Wang next door, and the old man pushing * in front will be overwritten.
SearchSourceBuilder.query (querybuilders.matchquery ("title", "Lao Wang next door"));
wrapper.setSearchSourceBuilder(searchSourceBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
//Thinking: Why is it covered? Because it is not technically possible at present, the query tree has been established, and the es bottom layer does not provide an API to continue adding query conditions to the specified level of the tree.
}
/**
* Unsupported mixed query 2: Take off pants and put P self-deception series
*/
@Test
public void testNotSupportMix2() {
//syntax that ee satisfies.
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Wrapper.eq(Document::getTitle, "old man")
. match(Document::getContent, "push *");
//The structure of SearchSourceBuilder is new by itself, and it is not equivalent to taking off pants and putting P through mapper. getSearchSourceBuilder (wrapper), so the above query conditions will naturally not take effect.
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.minScore(10.5f);
wrapper.setSearchSourceBuilder(searchSourceBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Conclusion
Because the functions supported by RestHighLevel provided by ES are too numerous, although I am still integrating all kinds of new functions non-stop, fixing the problems of users' feedback and optimizing the performance of existing codes, it is inevitable that some functions will not meet your current needs. Please forgive me, EE has only been born for one year, and it is impossible to be perfect. Please give us some time. We have been rushing without any return. The great progress made in this year is obvious to all. These so-called shortcomings will be solved, just as new energy vehicles will gradually replace fuel vehicles in the future. Those so-called problems will not be a problem in time, Ulla!