I do have the documents like below in my index
{
"bookName" : "coolbook",
"timeStamp" : "2018-11-19T12:52:17.000Z",
"referenceId" : "auth_test_01_01_000004",
"peoplestatus" : [
{
"personId" : "p1",
"status" : "like"
},
{
"personId" : "p2",
"status" : "dislike"
},{
"personId" : "p3",
"status" : "netrual"
}
]
}
Now I want to query the aggregations of book count for person p1,p2 like below
the counts of books
p1-liked but p2-disliked
p1,p2 both liked
p2-disliked but p1-liked
p1,b2 both disliked
Thanks for your help
Since you require buckets with different filter for each bucket, filters aggregation is best fit for this.
As per your comment there will be two person ids to be compared following is the query for your following two combinations:
P1 liked but P2 disliked
P1 and P2 both liked
{
"query": {
"match_all": {}
},
"aggs": {
"books": {
"filters": {
"filters": {
"P1L_P2DL": {
"bool": {
"must": [
{
"nested": {
"path": "peoplestatus",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"peoplestatus.personId": "p1"
}
},
{
"term": {
"peoplestatus.status": "like"
}
}
]
}
}
]
}
}
}
},
{
"nested": {
"path": "peoplestatus",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"peoplestatus.personId": "p2"
}
},
{
"term": {
"peoplestatus.status": "dislike"
}
}
]
}
}
]
}
}
}
}
]
}
},
"L1N3": {
"bool": {
"must": [
{
"nested": {
"path": "peoplestatus",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"peoplestatus.personId": "p1"
}
},
{
"term": {
"peoplestatus.status": "like"
}
}
]
}
}
]
}
}
}
},
{
"nested": {
"path": "peoplestatus",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"peoplestatus.personId": "p2"
}
},
{
"term": {
"peoplestatus.status": "like"
}
}
]
}
}
]
}
}
}
}
]
}
}
}
}
}
},
"size": 0
}
Related
I have created a composite query for aggregating on 2 different attributes as below -
{
"from": 0,
"size": 0,
"query": {
"bool": {
"must": [
{
"nested": {
"query": {
"script": {
"script": {
"source": "params.territoryIds.contains(doc['territoryHierarchy.id'].value) ",
"lang": "painless",
"params": {
"territoryIds": [
12345678
]
}
},
"boost": 1.0
}
},
"path": "territoryHierarchy",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
},
{
"bool": {
"should": [
{
"nested": {
"query": {
"script": {
"script": {
"source": "doc['forecastHeaders.id'].value == params.id && doc['forecastHeaders.revenueCategory'].value == params.revenueCategory ",
"lang": "painless",
"params": {
"revenueCategory": 0,
"id": 987654321
}
},
"boost": 1.0
}
},
"path": "forecastHeaders",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
},
{
"nested": {
"query": {
"script": {
"script": {
"source": "doc['forecastHeaders.id'].value == params.id && doc['forecastHeaders.revenueCategory'].value == params.revenueCategory ",
"lang": "painless",
"params": {
"revenueCategory": 0,
"id": 987654321
}
},
"boost": 1.0
}
},
"path": "forecastHeaders",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
},
{
"terms": {
"revnWinProbability": [
40,
50
],
"boost": 1.0
}
},
{
"terms": {
"revenueStatus.keyword": [
"OPEN"
],
"boost": 1.0
}
},
{
"range": {
"recordUpdateTime":{
"gte":1655117440000
}
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
},
"version": true,
"aggregations": {
"TopLevelAggregation": {
"composite" : {
"size" : 10000,
"sources" : [
{
"directs": {
"terms": {
"script": {
"source": "def territoryNamesList = new ArrayList(); def name; def thLength = params._source.territoryHierarchy.length; for(int i = 0; i< thLength;i++) { def thRecord = params._source.territoryHierarchy[i]; if (params.territoryIds.contains(thRecord.id) && i+params.levelToReturn < thLength) { territoryNamesList.add(params._source.territoryHierarchy[i+params.levelToReturn].name);} } return territoryNamesList;",
"lang": "painless",
"params": {
"territoryIds": [
12345678
],
"levelToReturn": 1
}
}
}
}
},
{
"qtr" : {
"terms" : {
"field" : "quarter.keyword",
"missing_bucket" : false,
"order" : "asc"
}
}
}
]
},
"aggregations": {
"revnRevenueAmount": {
"sum": {
"script": {
"source": "doc['revenueTypeCategory.keyword'].value != 'Other' ? doc['revnRevenueAmount']:doc['revnRevenueAmount']",
"lang": "painless"
},
"value_type": "long"
}
}
}
}
}
}
So this query does a composite aggregation based on two different terms aggregations, directs and qtr, and it works fine.
Now I am trying to create a corresponding spring data java client implementation for it. So I have created the code as below -
BoolQueryBuilder baseQueryBuilder = getQueryBuilder(searchCriteria);
List<TermsAggregationBuilder> aggregationBuilders = getMultiBaseAggregationBuilders(searchCriteria, baseQueryBuilder);
Where the bool query supplies the first part of the bool query and the getMultiBaseAggregationBuilders method returns the 2 different terms aggregations shown in the query above - directs and qtr. Now I am not finding any API to send this list of terms aggregations to the composite aggregation builder. Would be really grateful if someone can give me a pointer as to how this list of terms aggregations can be used inside the composite aggregation builder so the same can be achieved in the java code as it shows in the elastic query above. Thanks in advance.
I have a set of the following phrases: [remix], [18+], etc. How can I make a search by one character, for example "[", to find all these variants ?
Right now I have the following analyzers config:
{
"analysis": {
"analyzer": {
{ "bigram_analyzer": {
{ "type": "custom",
{ "tokenizer": { "keyword",
{ "filter": [
{ "lowercase",
"bigram_filter".
]
},
{ "full_text_analyzer": {
{ "type": "custom",
{ "tokenizer": { "ngram_tokenizer",
{ "filter": [
"lowercase"
]
}
},
{ "filter": {
{ "bigram_filter": {
{ "type": "edge_ngram",
{ "max_gram": 2
}
},
{ "tokenizer": {
{ "ngram_tokenizer": {
{ "type": "ngram",
{ "min_gram": 3,
{ "max_gram": 3,
{ "token_chars": [
{ "letter",
{ "digit",
{ "symbol",
"punctuation"
]
}
}
}
}
Mapping occurs at the java entity level using the spring boot data elasticsearch starter
If I understand your problem correctly - you want to implement an autocomplete analyzer that will return any term that starts with [ or any other character. To do so you can create a custom analyzer using ngram autocomplete. Here is an example:
Here is the testing index:
PUT /testing-index-v3
{
"settings": {
"number_of_shards": 1,
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 15
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}
},
"mappings": {
"properties": {
"term": {
"type": "text",
"analyzer": "autocomplete"
}
}
}
}
Here is the documents input:
POST /testing-index-v3/_doc
{
"term": "[+18]"
}
POST testing-index-v3/_doc
{
"term": "[remix]"
}
POST testing-index-v3/_doc
{
"term": "test"
}
And finally our search:
GET testing-index-v3/_search
{
"query": {
"match": {
"term": {
"query": "[remi",
"analyzer": "keyword",
"fuzziness": 0
}
}
}
}
As you can see I chose the keyword tokenizer for the autocomplete filter. I'm using ngram filter with min_gram: 1 and max_gram 15 which means our query will be separated into tokens like this:
input-query = i, in, inp, inpu, input .. and etc. Separates up to 15 tokens. This is wanted only at indexing time. Looking at the query we specify keyword analyzer as well - this analyzer is for the search time and it hard matches results. Here are some example searches and results:
GET testing-index-v3/_search
{
"query": {
"match": {
"term": {
"query": "[",
"analyzer": "keyword",
"fuzziness": 0
}
}
}
}
result:
"hits" : [
{
"_index" : "testing-index-v3",
"_type" : "_doc",
"_id" : "w5c_IHsBGGZ-oIJIi-6n",
"_score" : 0.7040055,
"_source" : {
"term" : "[remix]"
}
},
{
"_index" : "testing-index-v3",
"_type" : "_doc",
"_id" : "xJc_IHsBGGZ-oIJIju7m",
"_score" : 0.7040055,
"_source" : {
"term" : "[+18]"
}
}
]
GET testing-index-v3/_search
{
"query": {
"match": {
"term": {
"query": "[+",
"analyzer": "keyword",
"fuzziness": 0
}
}
}
}
result:
"hits" : [
{
"_index" : "testing-index-v3",
"_type" : "_doc",
"_id" : "xJc_IHsBGGZ-oIJIju7m",
"_score" : 0.7040055,
"_source" : {
"term" : "[+18]"
}
}
]
Hope this answer helps you. Good luck with your adventures with elasticsearch!
Something similar i am trying to achieve for below JSON.
SELECT * FROM TABLE_NAME WHERE ORGID = "BACKENDORG" AND TYPE = "AUDIT" AND
(sessionId LIKE '%16ECA064B298356B%' OR loginUserId LIKE '%16ECA064B298356B%' OR txnId LIKE '%16ECA064B298356B%');
{
"sessionId": "16ECA064B298356B",
"message": "2019-12-03T05:29:13.217Z [http-nio-8080-exec-4] INFO http-nio-8080-exec-4 QueryController backendorg 16CFAFCCFB14D9A3 16ECA064B298356B 16ECA3A4EFA026BF
"type": "audit",
"orgId": "backendorg",
"loginUserId": "16CFAFCCFB14D9A3",
"txnId": "16ECA3A4EFA026BF"
}
trying to write a LIKE query using BoolQueryBuilder, Here is my query
{
"query": {
"bool": {
"must": [
{
"term": {
"orgId": {
"value": "backendorg",
"boost": 1
}
}
},
{
"term": {
"type": {
"value": "audit",
"boost": 1
}
}
},
{
"bool": {
"should": [
{
"wildcard": {
"sessionId": {
"wildcard": "16ECA064B298356B",
"boost": 1
}
}
},
{
"wildcard": {
"loginUserId": {
"wildcard": "16ECA064B298356B",
"boost": 1
}
}
},
{
"wildcard": {
"txnId": {
"wildcard": "16ECA064B298356B",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"minimum_should_match": "1",
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}
Above query should return the above JSON result, but it showing zero hits.
It would be helpful if someone pointed out the issue.
I want to filter a elastic search query to find salary of a employee greater than or less than a particular amount.What should be the filtered query??
{
"from": 0,
"size": 24,
"query": {
"bool": {
"must": {
"multi_match": {
"query": "claims",
"fields": ["Employee"],
"fuzziness": "AUTO"
}
}
}
},
"highlight": {
"type": "unified",
"fields": {
"*": {}
}
}
}
You can use something like that for range query,
"query": {
"range" : {
"salary" : {
"gte" : "1000",
"lt" : "3000"
}
}
}
How to use Elasticsearch 1.6/1.7 version geo distance filter with bool term query like this. How and here two merge these two queries
Original query:
{
"query": {
"bool": {
"must": [
{
"term": {
"categories": "tv"
}
}
],
"should": [
{
"term": {
"subCategory": "led"
}
}
],
"minimum_should_match": 1,
"boost": 2
}
}
}
I want to search products with above bool query with distance of 10 miles
{
"filtered": {
"filter": {
"geo_distance": {
"distance": "10km",
"sellerInfoES.address.sellerLocation": "28.628978,77.21971479999999"
}
}
}
}
Thanks Val! Query is working, I am not getting any query parsing error. However this geo query is not returning and distance range result. I am using Elasticsearch 1.6 and stored sellerLocation as geo_point.Mapping:
{
"SellerInfoES": {
"type": "nested",
"properties": {
"sellerLocation": {
"type": "geo_point"
}
}
}
}
This geo_query is not working
{
"geo_distance": {
"distance": "100km",
"sellerLocation": {
"lat": 28.628978,
"lon": 77.21971479999999
}
}
}
You can combine both query/filters like this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"categories": "tv"
}
},
{
"nested": {
"path": "sellerInfoES",
"filter": {
"geo_distance": {
"distance": "10km",
"sellerInfoES.sellerLocation": {
"lat": "28.628978",
"lon":"77.21971479999999"
}
}
}
}
}
],
"should": [
{
"term": {
"subCategory": "led"
}
}
],
"minimum_should_match": 1,
"boost": 2
}
}
}
}
}