ElasticSearch should query - elasticsearch

I want to create ElasticSearch query which would be the same as this SQL query
select *
from main.adverts
where user_id = 4
and
(title ilike '%продать / купить%'
or description ilike '%продать / купить%'
)
My attempt is:
{
"query" :{
"bool" : {
"must" : [
{
"term" : {
"user.id" : {
"value" : 4,
"boost" : 1.0
}
}
}
],
"should" : [
{
"bool" : {
"must" : [
{
"match" : {
"title" : {
"query" : "продать",
"operator" : "OR",
"fuzzy_transpositions" : false,
"boost" : 1.0
}
}
},
{
"wildcard" : {
"title" : {
"wildcard" : "купить*",
"boost" : 1.0
}
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
{
"bool" : {
"must" : [
{
"match" : {
"description" : {
"query" : "продать",
"operator" : "OR",
"fuzzy_transpositions" : false,
"boost" : 1.0
}
}
},
{
"wildcard" : {
"description" : {
"wildcard" : "купить*",
"boost" : 1.0
}
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
}
But it doesn't work correctly. As the result of this query I got records which doesn't contain phrase "продать / купить".
I think that problem is in the "should" part of ElasticSearch query but can't get where is particular.
Could you point me where is my mistake?

It seems that I've found solution
{
"from" : 0, "size" : 60,
"_source" : ["title", "description"],
"query" :{
"bool" : {
"must" : [
{
"term" : {
"user.id" : {
"value" : 4,
"boost" : 1.0
}
}
},
{
"bool" : {
"must" : [
{
"match" : {
"title" : {
"query" : "продать",
"operator" : "OR",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : false,
"lenient" : false,
"zero_terms_query" : "NONE",
"boost" : 1.0
}
}
},
{
"wildcard" : {
"title" : {
"wildcard" : "купить*",
"boost" : 1.0
}
}
}
],
"should" : [
{
"bool" : {
"must" : [
{
"match" : {
"description" : {
"query" : "продать",
"operator" : "OR",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : false,
"lenient" : false,
"zero_terms_query" : "NONE",
"boost" : 1.0
}
}
},
{
"wildcard" : {
"description" : {
"wildcard" : "купить*",
"boost" : 1.0
}
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
}

Related

How do I query nested with normal match query together?

I want to fire nestedQuery on addresses and multiMatchQuery on name in single query. I tried few ways but I am getting "[bool] query does not support [nested]". I don't know whether this is possible or not (ES version: 7.x).
When I separately querying (i.e.nestedQuery() & multiMatchQuery()) that time it is working fine.
Please help me with that.
This is the mapping I am using:
{
"employee" : {
"mappings" : {
"properties" : {
"addresses" : {
"type" : "nested",
"properties" : {
"permanentAddress" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"TemporaryAddress" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"id" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
1. {
"query": {
"nested": {
"path": "addresses",
"query": {
"bool": {
"must": [
{ "match": { "addresses.permanentAddress": "xxx" } }
]
}
},
"score_mode": "avg"
}
}
}
2. {
"query": {
"bool": {
"must" : [
{
"multi_match" : {
"query" : "xxx",
"fields" : [
"name^1.0"
],
"type" : "best_fields",
"boost" : 1.0
}
}
]
}
}
}
nestedQuery() = looking for xxx value in addresses.permanentAddress
multi_match() = looking for xxx value in name
If value of name or addresses.permanentAddress matches with xxx then returns the result.
"bool" : {
"should" : [
{
"bool" : {
"must" : [
{
"match" : {
"name" : {
"query" : "xxx",
"operator" : "AND",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : true,
"lenient" : false,
"zero_terms_query" : "NONE",
"auto_generate_synonyms_phrase_query" : true,
"boost" : 1.0
}
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
{
"nested" : {
"query" : {
"bool" : {
"must" : [
{
"match" : {
"employee.permanentAddress" : {
"query" : "xxx",
"operator" : "AND",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : true,
"lenient" : false,
"zero_terms_query" : "NONE",
"auto_generate_synonyms_phrase_query" : true,
"boost" : 1.0
}
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
"path" : "employee",
"ignore_unmapped" : false,
"score_mode" : "none",
"boost" : 1.0,
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
This Bool query with nested worked for me and with that I can able to check parent's as well as nested property.

ElasticSearch span near query not producing expected results with nested span queries

I have an odd scenario. I have a document which contains the text "6 Music Live Hour".
The second part of the query - span_term matching "Hour" produces no results when written as below
{
"span_near" : {
"clauses" : [
{
"span_near" : {
"clauses" : [
{
"span_term" : {
"all_field" : {
"value" : "6",
"boost" : 1.0
}
}
},
{
"span_multi" : {
"match" : {
"wildcard" : {
"all_field" : {
"wildcard" : "M*c",
"boost" : 1.0
}
}
},
"boost" : 1.0
}
}
],
"slop" : 0,
"in_order" : true,
"boost" : 1.0
}
},
{
"span_term" : {
"all_field" : {
"value" : "Hour",
"boost" : 1.0
}
}
}
],
"slop" : 2147483647,
"in_order" : true,
"boost" : 1.0
}
}
However, when I change this to a wildcard query it produces the expected result. See below.
{
"span_near" : {
"clauses" : [
{
"span_near" : {
"clauses" : [
{
"span_term" : {
"all_field" : {
"value" : "6",
"boost" : 1.0
}
}
},
{
"span_multi" : {
"match" : {
"wildcard" : {
"all_field" : {
"wildcard" : "M*c",
"boost" : 1.0
}
}
},
"boost" : 1.0
}
}
],
"slop" : 0,
"in_order" : true,
"boost" : 1.0
}
},
{
"span_multi" : {
"match" : {
"wildcard" : {
"all_field" : {
"wildcard" : "Hour",
"boost" : 1.0
}
}
},
"boost" : 1.0
}
}
],
"slop" : 2147483647,
"in_order" : true,
"boost" : 1.0
}
}
Please can anyone advise on what I'm doing incorrectly in the first query.
Converting the text to lowercase and then building the term query produced the expected results.

Elastic search fetch +1 and -1 docuemnt for an id with sort and filter query

I have a query, this query returns a document and I have to retrieve the doc+1 and doc-1. Any suggestions. I cannot afford to do split this query?
EDIT:
The query:
{
"bool" : {
"must" : [
{
"match" : {
"company_id" : {
"query" : "5d10b28a05b69a01f9284913",
"operator" : "OR",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : true,
"lenient" : false,
"zero_terms_query" : "NONE",
"auto_generate_synonyms_phrase_query" : true,
"boost" : 1.0
}
}
}
],
"must_not" : [
{
"terms" : {
"status" : [
"IN_ACTIVE"
],
"boost" : 1.0
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
}

How to built AND condition between should and must elastic search bool query

Here is the sample USER document
{
"id" : "1234567",
"userId" : "testuser01",
"firstName" : "firstname",
"lastName" : "lastname",
"orgId" : "567890",
"phoneNumber" : "1234567890"
}
I want to build a search query where in I want to pull all those users which belong to particular orgId AND which matches the search text entered by user in any of the fields (userId, firstname, etc.)
ex. if search is made using text "first", I want to pull all those records which belong to particular orgId AND fields containing first in it.
Sample query I am trying is
"query" : {
"bool" : {
"must" : [
{
"term" : {
"orgId.keyword" : {
"value" : "567890",
"boost" : 1.0
}
}
}
],
"should" : [
{
"simple_query_string" : {
"query" : "first*",
"fields" : [
"lastName^1.0"
],
"flags" : -1,
"default_operator" : "or",
"lenient" : false,
"analyze_wildcard" : true,
"boost" : 1.0
}
},
{
"simple_query_string" : {
"query" : "first*",
"fields" : [
"userId^1.0"
],
"flags" : -1,
"default_operator" : "or",
"lenient" : false,
"analyze_wildcard" : true,
"boost" : 1.0
}
},
{
"simple_query_string" : {
"query" : "first*",
"fields" : [
"orgId^1.0"
],
"flags" : -1,
"default_operator" : "or",
"lenient" : false,
"analyze_wildcard" : true,
"boost" : 1.0
}
},
{
"simple_query_string" : {
"query" : "first*",
"fields" : [
"firstName^1.0"
],
"flags" : -1,
"default_operator" : "or",
"lenient" : false,
"analyze_wildcard" : true,
"boost" : 1.0
}
},
{
"simple_query_string" : {
"query" : "first*",
"fields" : [
"phoneNumber^1.0"
],
"flags" : -1,
"default_operator" : "or",
"lenient" : false,
"analyze_wildcard" : true,
"boost" : 1.0
}
},
{
"simple_query_string" : {
"query" : "first*",
"fields" : [
"id^1.0"
],
"flags" : -1,
"default_operator" : "or",
"lenient" : false,
"analyze_wildcard" : true,
"boost" : 1.0
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
"sort" : [
{
"userId.keyword" : {
"order" : "asc"
}
}
]
}
Issue I am facing is, I want to have AND condition between MUST and SHOULD.
You don't need to specify the query for each field in query_string query. Rather you can specify the list of fields as below:
{
"query": {
"bool": {
"must": [
{
"term": {
"orgId.keyword": {
"value": "567890",
"boost": 1
}
}
},
{
"simple_query_string": {
"query": "first*",
"fields": [
"lastName^1.0",
"userId^1.0",
"orgId^1.0",
"firstName^1.0",
"phoneNumber^1.0",
"id^1.0"
]
}
}
]
}
},
"sort": [
{
"userId.keyword": {
"order": "asc"
}
}
]
}
Also to answer
How to built AND condition between should and must elastic search bool query?
here is a sample query for this:
{
"query": {
"bool": {
"must": [
{
"term": {
"field1": "someval"
}
},
{
"bool": {
"should": [
{
"terms": {
"field2": [
"v1",
"v2"
]
}
},
{
"query_string": {
"query": "this AND that OR thus"
}
}
]
}
}
]
}
}
}

Elasticsearch bool query formation with multiple must clause

I have a query like the following -
{
"query": {
"bool": {
"must": {
"bool" : { "should": [
{ "match": { "camp_id": "Elasticsearch" }},
{ "match": { "camp_id": "Solr" }} ] }
},
"must": {
"bool" : { "should": [
{ "match": { "ad_id": "Elastic" }},
{ "match": { "ad_id": "dummy" }} ] }
},
"must_not": { "match": {"authors": "radu gheorge" }},
.....
.....
}
}
}
In short, (camp_id = 'elasticsearch' or camp_id = 'solr') AND (ad_id = 'elasticsearch' or ad_id = 'solr') ....
After good amount of research, I wrote the following java code -
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
final BoolQueryBuilder finalBoolQuery = new BoolQueryBuilder();
BoolQueryBuilder campaignBoolQuery = null;
if (campaignIds != null) {
campaignBoolQuery = QueryBuilders.boolQuery();
for (int campaignId : campaignIds) {
campaignBoolQuery.should(QueryBuilders.matchQuery("camp_id", campaignId));
}
}
BoolQueryBuilder creativeBoolQuery = null;
if (creativeIds != null) {
creativeBoolQuery = QueryBuilders.boolQuery();
for (int creativeId : creativeIds) {
creativeBoolQuery.should(QueryBuilders.matchQuery("ad_id", creativeId));
}
}
finalBoolQuery.must(campaignBoolQuery);
finalBoolQuery.must(creativeBoolQuery);
searchSourceBuilder.query(finalBoolQuery).size(9999);
System.out.println(searchSourceBuilder.toString());
With the above code, I expected that I would have 1 must clause for 'camp_id' and another 1 for 'ad_id' but following is what I got -
{
"size" : 9999,
"query" : {
"bool" : {
"must" : [
{
"bool" : {
"should" : [
{
"match" : {
"camp_id" : {
"query" : 1,
"operator" : "OR",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : true,
"lenient" : false,
"zero_terms_query" : "NONE",
"boost" : 1.0
}
}
},
{
"match" : {
"camp_id" : {
"query" : 2,
"operator" : "OR",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : true,
"lenient" : false,
"zero_terms_query" : "NONE",
"boost" : 1.0
}
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
{
"bool" : {
"should" : [
{
"match" : {
"ad_id" : {
"query" : 1,
"operator" : "OR",
"prefix_length" : 0,
"max_expansions" : 50,
"fuzzy_transpositions" : true,
"lenient" : false,
"zero_terms_query" : "NONE",
"boost" : 1.0
}
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
}
There is only one must clause which wraps both camp_id and ad_id. Can someone please point out what am I missing? I am using elastic search version - 5.5.0 and jest - 2.4.0 as my java client.
your outer bool sample query contains two must clauses, however that must be a single must clause, that contains of an array of objects. I suppose you are overwriting the first must clause with the second, when calling must() twice.

Resources