I was trying to search the following case using BoolQueryBuilder in elasticsearch
select * from students where (name = "XXX" and rollno = 1) or (name = "YYY" and rollno = 2)
I have to build query builder for it.
Can anyone suggest me the BoolQueryBuilder to build the query.
ElasticSearch 6.1.2
Any help really appreciated.
This is java api to build the BooleanQueryBuilder condition
BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
booleanQuery.must(QueryBuilders.termQuery("name", "XXX"));
booleanQuery.must(QueryBuilders.termQuery("rollno", 1));
BoolQueryBuilder booleanQuery2 = QueryBuilders.boolQuery();
booleanQuery2.must(QueryBuilders.termQuery("name", "YYY"));
booleanQuery2.must(QueryBuilders.termQuery("rollno", 2));
BoolQueryBuilder boolQueryBuilder3 = QueryBuilders.boolQuery();
boolQueryBuilder3.should(booleanQuery2);
boolQueryBuilder3.should(booleanQuery);
Here it is:
GET students/_search
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"name": {
"value": "XXX"
}
}
},
{
"term": {
"rollno": {
"value": "1"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"name": {
"value": "YYY"
}
}
},
{
"term": {
"rollno": {
"value": "2"
}
}
}
]
}
}
]
}}}
Basically, bool compound query can apply into deeper level. The rest is about how you use in case of OR or AND operation.
In this case, should map to OR, and must map to AND.
Cheers,
Related
I am ne on elastichSearch. i am trying the exact match and and operation. I tried so many ways but all the time the response is mess for me. It is like fuzzy match. I need exact match as RDBMS
SELECT * FROM IP="1.1.1.1" AND NAME="ETH1/10"
Thanks in advance.
If You need the exact match than instead of match query use term query
Adding a working example
Index mapping
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"ip" :{
"type" : "ip"
}
}
}
}
Index sample doc
{
"name" : "ETH1/10",
"ip" : "1.1.1.1"
}
And search query
{
"query": {
"bool": {
"filter": [ --> use `filter` as pointed by #Val in the comment.
{
"term": {
"ip": "1.1.1.1"
}
},
{
"term": { --> `term` query for exact match.
"name": "ETH1/10"
}
}
]
}
}
}
And search result
"hits": [
{
"_index": "65167713",
"_type": "_doc",
"_id": "1",
"_score": 0.0,
"_source": {
"name": "ETH1/10",
"ip": "1.1.1.1"
}
}
]
How about this?
{
"query":{
"bool":{
"must":[
{
"match":{
"IP":"1.1.1.1"
}
},
{
"match":{
"NAME":"ETH1/10"
}
}
]
}
}
}
}
Below query will do filter and aggregation how to translate this to java code. Query works from postman the same needs to be converted into java using java client api. and i am using rest high level client as elastic search client. i tried with the below java code but the generated query is bit different than the the actual below is java code which i have tried.
BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
booleanQuery.filter(QueryBuilders
.queryStringQuery(String.join(" OR ", exactMatchThese))
.field("events.recommendationData.exceptionId"));
QueryBuilder queryBuilder = QueryBuilders.nestedQuery("events.recommendationData", booleanQuery, ScoreMode.None);
Search Query which is working
GET <index-name>/_search
{
"query": {
"bool": {
"filter": [
{
"nested": { --> note
"path": "events.recommendationData",
"query": {
"query_string": {
"query": "\"1\" OR \"2\"",
"fields": [
"events.recommendationData.exceptionId"
],
"type": "best_fields",
"default_operator": "or",
"max_determinized_states": 10000,
"enable_position_increments": true,
"fuzziness": "AUTO",
"fuzzy_prefix_length": 0,
"fuzzy_max_expansions": 50,
"phrase_slop": 0,
"escape": false,
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1
}
}
}
}
]
}
},
"size": 1,
"aggs": {
"genres": {
"nested": {
"path": "events.recommendationData.recommendations"
},
"aggs": {
"nested_comments_recomms": {
"terms": {
"field": "events.recommendationData.recommendations.recommendationType"
}
}
}
}
}
}
Below Search Query Generated from above java code which i have mentioned and is not working.
{
"query": {
"nested": {
"query": {
"bool": {
"filter": [
{
"query_string": {
"query": "\"1\" OR \"2\"",
"fields": [
"events.recommendationData.exceptionId^1.0"
],
"type": "best_fields",
"default_operator": "or",
"max_determinized_states": 10000,
"enable_position_increments": true,
"fuzziness": "AUTO",
"fuzzy_prefix_length": 0,
"fuzzy_max_expansions": 50,
"phrase_slop": 0,
"escape": false,
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"path": "events.recommendationData",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1
}
},
"aggregations": {
"recommendationTypes": {
"terms": {
"field": "events.recommendationData.recommendations.recommendationType",
"size": 10,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
}
}
}
Your inner-most query block is query string i.e.
QueryStringQueryBuilder queryString = QueryBuilders
.queryStringQuery(String.join(" OR ", exactMatchThese));
This is the query part of nested query hence we create a nested query and assign the above query to it as written below,
NestedQueryBuilder nestedQuery = QueryBuilders
.nestedQuery("events.recommendationData", queryString, ScoreMode.None);
Finally add the above query to the filter clause of bool query,
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().filter(nestedQuery);
All together this is,
QueryStringQueryBuilder queryString = QueryBuilders
.queryStringQuery(String.join(" OR ", exactMatchThese));
NestedQueryBuilder nestedQuery = QueryBuilders
.nestedQuery("events.recommendationData", queryString, ScoreMode.None);
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().filter(nestedQuery);
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"
}
}
}
I have 3 document,
{
"category":[{"id":"1"},{"id":"2"},{"id":"3"}]
}
{
"category":[{"id":"1"},{"id":"4"}]
}
{
"category":[]
}
How I can find document which have category.id in (2,3) like mysql,
also which type of DSL query I need to use in java api querybuilder
You can use the bool query with should clause to find all documents which contain either of the requested ids. Here is how the Query DSL would like
{
"query": {
"bool": {
"should": [
{"term": {
"category.id": {
"value": "2"
}
}},
{"term": {
"category.id": {
"value": "3"
}
}
}
]
}
}
}
Here's how you would use the Java API
QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("category.id", "2"))
.should(QueryBuilders.matchQuery("category.id", "1"));
If the id field is not-analysed, you can also use the terms query. More info here https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
Here's how your query should look like:
{
"query": {
"bool": {
"filter": [
{
"term": {
"category.id": "1"
}
},
{
"term": {
"category.id": "2"
}
}
]
}
}
}
Like this:
{
"filter": {
"terms": {
"category.id": ["2", "3"]
}
}
}
In the following query I want to filter the query results to size medium and color blue but I want aggregations to ignore that the color blue is applied.
{
"query":{
"bool" {
"must": {
"query_string": {
"query": "foo"
}
},
"should": {
// deferred
}
}
},
"filter": {
"term": {"size": "m"}
},
"aggregations": {
// deferred
},
"post_filter":{
"term":{"color":"blue"}
}
}
The problem is whenever the post_filter is present the size filter no longer has any effect on the query result. What am I missing?
EDIT: elasticsearch version 1.5.1
Your filter is acting as a post_filter, i.e. it gets overwritten by the subsequent post_filter.
You should either have a post_filter that covers both the size and color (if you want these excluded from the aggregation) or move the size filter into a filtered query:
"query": {
"filtered": {
"query":{
"bool" {
"must": {
"query_string": {
"query": "foo"
}
},
"should": {
// deferred
}
}
},
"filter" : {
"term": {"size": "m"}
}
}
}
Which version of elasticsearch you are using?
If you want certain filter to be considered in aggregation it should be inside a query scope (so use filtered query), any other filter is considered out of the query scope so won't be considered for aggregation count but will affect the final output.
Change the query as below:
{
"query": {
"filtered": {
"query": {
"bool": {
"must": {
"query_string": {
"query": "foo"
}
},
"should": {
//deferred
}
}
},
"filter": {
"term": {
"size": "m"
}
}
}
},
"aggregations": {
//deferred
},
"post_filter": {
"term": {
"color": "blue"
}
}
}
This will aggregate on result of size:m only but final result will be on color:blue and size:m