Is there any way to write by query_string this query?
(field_one : "word_one" OR "word_two" OR "word_three") AND (field_one
: "word_four" OR "word_five" OR "word_six") AND (field_two :
"word_seven" OR "word_eigth" OR "word_nine")
Like this, but with three fields and three queries?
"query": {
"bool": {
"must": [
{
"query_string": {
"fields": [
"my_search_field"
],
"query": "my_search_query"
}
}
]
}
}
I tried to write it using filter:
"filter": [
{
"bool": {
"filter": [
{
"bool": {
"should": should_phrases_a, #words by field_one
"minimum_should_match": 1
}
},
{
"bool": {
"should": should_phrases_b, #words by field_one
"minimum_should_match": 1
}
},
{
"bool": {
"should": should_phrases_c, #words by field_two
"minimum_should_match": 1
}
}
]
}
}
]
Where should_phases_a/b/c look like list of:
{"bool": {"should": [{
"match_phrase": {
"field_one": "word_one"
}
}
],
"minimum_should_match": 1
}
}
But it didn't worked for me. It was good only with one_field intersection (without part with should_phrases_c):
(field_one : "word_one" OR "word_two" OR "word_three") AND (field_one
: "word_four" OR "word_five" OR "word_six")
You can specify fields in query
Query
{
"query": {
"query_string": {
"query": """
(field_one:word_one OR word_two OR word_three)
AND (field_one:word_four OR word_five OR word_six)
AND (field_two:word_seven OR word_eigth OR word_nine)
"""
}
}
}
Related
I have two Elasticsearch queries (which I use via the elastic package in R).
One query gathers the number of times a feature is loaded, the other gathers the number of times a feature is unloaded.
My needs have now changed in that I need to gather both types of data/states together, in the same dataset (the state can either be TRUE or FALSE and I want to gather both in the same dataset).
What I want to do: To identify both cases where visible is either TRUE or FALSE.
Therefore, I want to know what the best approach is: should I (attempt to) merge the queries or I should use an or-type operator?
If it is the latter, how would I go about it?
For completeness, here are my minified queries (unminified versions are at the end of this question):
loads_body <- '{"size":0,"query":{"bool":{"must":[{"match":{"merchant":"a6xzTHtpQs"}},{"term":{"visible":true}},{"range":{"time":{"gte":"2018-04-02T06:00:00","lte":"2018-04-03T05:59:59","time_zone":"+00:00"}}}]}},"aggs":{"daily":{"date_histogram":{"field":"time","interval":"hour","time_zone":"+00:00","min_doc_count":0,"extended_bounds":{"min":"2018-04-02T06:00:00","max":"2018-04-03T05:59:59"}}}}}'
and
unloads_body <- '{"size":0,"query":{"bool":{"must":[{"match":{"merchant":"a6xzTHtpQs"}},{"term":{"visible":false}},{"range":{"time":{"gte":"2018-04-02T06:00:00","lte":"2018-04-03T05:59:59","time_zone":"+00:00"}}}]}},"aggs":{"daily":{"date_histogram":{"field":"time","interval":"hour","time_zone":"+00:00","min_doc_count":0,"extended_bounds":{"min":"2018-04-02T06:00:00","max":"2018-04-03T05:59:59"}}}}}'
Unminified queries:
loads_body <- '{
"size":0,
"query": {
"bool": {
"must":[ {
"match": {
"merchant": "a6xzTHtpQs"
}
}
,
{
"term": {
"visible": true
}
}
,
{
"range": {
"time": {
"gte": "2018-04-02T06:00:00", "lte": "2018-04-03T05:59:59", "time_zone": "+00:00"
}
}
}
]
}
}
,
"aggs": {
"daily": {
"date_histogram": {
"field":"time",
"interval":"hour",
"time_zone":"+00:00",
"min_doc_count":0,
"extended_bounds": {
"min": "2018-04-02T06:00:00", "max": "2018-04-03T05:59:59"
}
}
}
}
}'
and
unloads_body <- '{
"size":0,
"query": {
"bool": {
"must":[ {
"match": {
"merchant": "a6xzTHtpQs"
}
}
,
{
"term": {
"visible": false
}
}
,
{
"range": {
"time": {
"gte": "2018-04-02T06:00:00", "lte": "2018-04-03T05:59:59", "time_zone": "+00:00"
}
}
}
]
}
}
,
"aggs": {
"daily": {
"date_histogram": {
"field":"time",
"interval":"hour",
"time_zone":"+00:00",
"min_doc_count":0,
"extended_bounds": {
"min": "2018-04-02T06:00:00", "max": "2018-04-03T05:59:59"
}
}
}
}
}'
Yes you can use a single query and sub aggregations to do what you are looking for. Something along the lines of
{
"query":{
"bool":{
"must":[
{
"match":{
"merchant":"a6xzTHtpQs"
}
},
{
"range":{
"time":{
"gte":"2018-04-02T06:00:00",
"lte":"2018-04-03T05:59:59",
"time_zone":"+00:00"
}
}
}
]
}
},
"aggs":{
"Visible_agg":{
"terms":{
"field":"visible"
},
"aggs":{
"daily":{
"date_histogram":{
"field":"time",
"interval":"hour",
"time_zone":"+00:00",
"min_doc_count":0,
"extended_bounds":{
"min":"2018-04-02T06:00:00",
"max":"2018-04-03T05:59:59"
}
}
}
}
}
}
}
This should produce the histograms in two buckets one for "visible": true and other for "visible":false
Is this what you are looking for?
when I am trying to comprise a compound bool query that has a fuzzy must requirement and several should reqs with one being a wildcard, I run into this error message. So far, no alterations to the syntax have helped me to resolve this issue.
The query:
{
"query": {
"bool": {
"must": {
"fuzzy": {
"message": "<fuzzy string>",
"fuzziness": "auto"
}
},
"should": [
{ "query": { "message": "<string>" } },
{ "query": { "message": "<string>" } },
{ "wildcard":
{
"query": { "message": "<partial string*>"}
}
}
],
"minimum_should_match": "50%"
}
}
}
The text inside <> is replaced with my searched string.
You need to replace query with match in your bool/should clause:
> { "query": {
> "bool": {
> "must": {
> "fuzzy": {
> "message": "<fuzzy string>",
> "fuzziness": "auto"
> }
> },
> "should": [
> {"match": {"message": "<string>"}}, <-- here
> {"match": {"message": "<string>"}}, <-- and here
> {"wildcard": {"query": {"message": "<partial string*>"}}}
> ],
> "minimum_should_match": "50%"
> } } }
I'm using Elasticsearch API and the schema of the document as follow
{
name: "",
born_year: "",
born_month: "",
born_day: "",
book_type: "",
price: <some number>,
country: ""
}
Now what I need is to get the document count per each name where born before 1995 (born_year + born_month + born_day < "20051220"). How can i achieve?
I tried this:
{
"query": {
"query_string": {
"query": "country:\"SL\""
}
},
"size": 0,
"aggs": {
"total": {
"terms": {
"field": "name"
}
}
}
}
But I have no idea how can I add filter for the birthday.
As mentioned by #val, you need to add a real date field that you can easily add by concatenating these three fields at creation time.
But how you filter based on date range, there are two ways and both of them will return different result sets
Now the level of filtering is your choice.
You mentioned querying on country field. But you have not mentioned at what level you want to filter on date range. I will give you queries for both the cases.
Mappings- assuming you create a date field.
{
name:"",
born_year:"",
born_month:"",
born_day:"",
book_type:"",
price:<some number>,
country:"",
date : ""
}
Case - 1) Filtering date range for name aggregations only, here documents count will not be effected by the date range filter
{
"query": {
"query_string": {
"query": "country:\"SL\""
}
},
"aggs": {
"total": {
"filter": {
"range": {
"date": {
"gte": "your_date_mx",
"lte": "your_date_min"
}
}
},
"aggs": {
"NAME": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
}
}
Case 2) In this case both your documents count and aggregation will be filtered for date range as we add date range filter at query level.
{
"query": {
"query_string": {
"query": "country:\"SL\""
},
"bool": {
"must": [
{
"range": {
"date": {
"gte": "your_date_mx",
"lte": "your_date_mic"
}
}
}
]
}
},
"aggs": {
"toal": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
So adding a filter to aggregation will effect only aggs count.
Edit -
Approach1) with groovy script try to concatinate the string and parse it to integer and then compare with your input date.
{
"query": {
"bool": {
"must": [
{}
],
"filter": {
"script": {
"script": {
"inline": "(doc['year'].value + doc['month'].value + doc['date'].value).toInteger() > 19910701",
"params": {
"param1": 19911122
}
}
}
}
}
}
}
Make sure when indexing index date(or month) with single digit like 6 as 06
2) Approach 2 - parse the string the exact date(preferred)
{
"query": {
"bool": {
"must": [
{}
],
"filter": {
"script": {
"script": {
"inline": "Date.parse('dd-MM-yyyy',doc['date'].value +'-'+ doc['month'].value +'-'+ doc['year'].value).format('dd-MM-yyyy') > param1",
"params": {
"param1": "04-05-1991"
}
}
}
}
}
}
}
Second approach is much better approach as you don't have to worry about the maintaing the string for each field(date, month, day) to later parse to proper int for comparing.
I want to convet the foll. sql query to elastic json query
select count(distinct(fk_id)),city_id from table
where status1 != "xyz" and satus2 = "abc" and
cr_date >="date1" and cr_date<="date2" group by city_id
Also is there any way of writing nested queries in elastic.
select * from table where status in (select status from table2)
The first query can be translated like this in the Elasticsearch query DSL:
curl -XPOST localhost:9200/table/_search -d '{
"size": 0,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"status2": "abc"
}
},
{
"range": {
"cr_date": {
"gt": "date1", <--- don't forget to change the date
"lt": "date2" <--- don't forget to change the date
}
}
}
],
"must_not": [
{
"term": {
"status1": "xyz"
}
}
]
}
}
}
},
"aggs": {
"by_cities": {
"terms": {
"field": "city_id"
},
"aggs": {
"fk_count": {
"cardinality": {
"field": "fk_id"
}
}
}
}
}
}'
Using Sql API In Elastic search, we can write queries and also we can translate them to elastic query
POST /_sql/translate
{
"query": "SELECT * FROM customer where address.Street='JanaChaitanya Layout' and Name='Pavan Kumar'"
}
Response for this is
{
"size" : 1000,
"query" : {
"bool" : {
"must" : [
{
"term" : {
"address.Street.keyword" : {
"value" : "JanaChaitanya Layout",
"boost" : 1.0
}
}
},
{
"term" : {
"Name.keyword" : {
"value" : "Pavan Kumar",
"boost" : 1.0
}
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
"_source" : {
"includes" : [
"Name",
"address.Area",
"address.Street"
],
"excludes" : [ ]
},
"docvalue_fields" : [
{
"field" : "Age"
}
],
"sort" : [
{
"_doc" : {
"order" : "asc"
}
}
]
}
Now we can use this result to query elastic search
For further details please go through this article
https://xyzcoder.github.io/elasticsearch/2019/06/25/making-use-of-sql-rest-api-in-elastic-search-to-write-queries-easily.html
my query is like this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"online": 1
}
},
{
"terms": {
"mediaType": "flash"
}
}
]
}
}
}
}
}
it raise a QueryParsingException [[comos_v2] [terms] filter does not support [mediaType]],of which the field "mediaType" exactly does not exist in mapping.
my question is why term filter does not raise the Exception?
The above is not a valid Query DSL. In the above Terms filter the values to "mediaType" field should be an array
It should be the following :
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"online": 1
}
},
{
"terms": {
"mediaType": ["flash"]
}
}
]
}
}
}
}
}
Its 2021 I'm using .keyword for an exact text match but you can just as easily omit:
{"query":
{"bool":
{"must":
[
{"term":
{"variable1.keyword":var1Here}
},
{"term":
{"variable2.keyword":var2Here}
}
]
}
}
}
Its simply a matter of "term" vs "terms". Very easy to miss the plural / single aspect of it.
I had a very similar error with this query, in which I was trying to delete a specific zone:
'{"query":{"terms":{"zoneid":25070}}}'
I was getting an error when I ran the above query.
As soon as changed "terms" to "term" the query executed with no issues, like this:
'{"query":{"term":{"zoneid":25070}}}'