Elastic Search SQL Equivalent - mysql

Im having some problems querying with elasticsearch. So basically i wanted to know the sql equivalent of elasticsearch.
Whats the equivalent elasticsearch syntax for this sql query ?
SELECT *
FROM people
WHERE name LIKE( $name% )
AND ( gender = 0 OR age < 18 )
AND id IN( 1, 2, 3 )
AND id NOT IN( 4, 5, 6 )
AND dead = 0
ORDER BY status desc,
TIME desc
* is just for example

Using boolean query (and nested boolean query ) allows you to express same things than sql request.
Terms query is validated when one of its elements is found (OR).
POST /index_name/people/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "John"
}
}
],
"filter": [
{
"bool": {
"must": [
{
"terms": {
"id": [
1,
2,
3
]
}
},
{
"term": {
"dead": 0
}
},
{
"bool": {
"should": [
{
"term": {
"gender": 0
}
},
{
"range": {
"age": {
"lt": 18
}
}
}
]
}
}
],
"must_not": [
{
"terms": {
"id": [
4,
5,
6
]
}
}
]
}
}
]
}
},
"sort": [
{
"status": {
"order": "desc"
},
"time": {
"order": "desc"
}
}
]
}

Related

Elastic search conversion php

I want to convert below MySQL query to elastic search in php
SELECT id,username,full_name
FROM users
WHERE id<>4 AND (username LIKE %john% OR full_name LIKE %full_name%)
LIMIT 50 OFFSET 0
Please educate
It'd be something like this:
GET /users/_search?pretty=true
{
"size": 50,
"query": {
"bool": {
"should": [
{
"terms": {
"username": "john"
}
},
{
"terms": {
"full_name": "full_name"
}
}
],
"must_not": [
{
"term": {
"id": "4"
}
}
]
}
}

Convert MySQL query (with where condition) to Elasticsearch query

I need to "transform" mysql query to Elasticsearch query. What is blocking me is "where" statement. Basically what I need is to find all items that are within distance of 25 miles based on latitude and longitude and where pickup is enabled OR where items do have delivery enabled and provided zip code
where
(
(
`enabled_pickup` = '1'
and(
ST_Distance_Sphere(
POINT(- 122.41941550000001 , 37.7749295) ,
geolocation
) / 1000 * 0.62137119223733
) <= 25
)
or(
`enabled_delivery` = '1'
`zip_code` = '94116'
)
)
and this is Elasticsearch query that is not working as expected
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"enabled_pickup": "1"
}
},
{
"geo_distance": {
"distance": "25 mi",
"geo_location": {
"lat": "37.7749295",
"lon": "-122.41941550000001"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"dispensary.delivery": "1"
}
},
{
"term": {
"zip_code": "94116"
}
}
]
}
}
]
}
}
]
}
}
}
can somebody please point me in right direction?
I was reading about the similar issue, you can give a try with below query. you can find a similar question being solved by this stackoverflow discussion
Hope this helps, Cheers!
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{"match": { "enabled_pickup": "1"}}
,{ "match": {
"geo_distance": {
"distance": "25 mi",
"geo_location": {
"lat": "37.7749295",
"lon": "-122.41941550000001"
}
}
}
}
]
}
,
"bool": {
"must": [
{ "match": {"dispensary.delivery": "1"} }
,{"match": {"zip_code": "94116"} }
]
}
}
]
}
}
}

Elasticsearch query that use 'terms' and 'missing' at same time

I am trying to use this query to get all documents with a closed or pending status or with no status at all.but this query always return nothing.
"query": {
"bool": {
"should": [
"terms": {
"status": ["closed","pending"]
},
"missing":{
"field":"status"
}
]
}
}
Individually the queries are working.If I use:
"query": {
"bool": {
"should": [
"terms": {
"status": ["closed","pending"]
}
]
}
}
then it returns 2 documents.
And if I use
"query": {
"bool": {
"should": [
"missing":{
"field":"status"
}
]
}
}
it returns 3.
These results are correct for each query.I just want to combine the 2 queries and get the result 5.What is wrong with the first query?
This ES 5.0 query and it should work on version 2.0
POST es1/example/_search
{
"query": {
"bool": {
"should": [
{
"terms": {
"status": [
"closed",
"pending"
]
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "status"
}
}
]
}
}
]
}
}
}

How does elasticsearch find the intersection of two search results like mysql?

query name sets from 20151216 to 20151217
{
"from": 0,
"size": 200,
"query": {
"bool": {
"must": {
"range": {
"DATE": {
"from": 20151216,
"to": 2015121617,
"include_lower": true,
"include_upper": true
}
}
}
}
},
"_source": {
"includes": [
"NAME"
],
"excludes": []
}
}
Another day
{
"from": 0,
"size": 200,
"query": {
"bool": {
"must": {
"range": {
"DATE": {
"from": 20151217,
"to": 2015121618,
"include_lower": true,
"include_upper": true
}
}
}
}
},
"_source": {
"includes": [
"NAME"
],
"excludes": []
}
}
If in MYSQL I will use the following SQL to solve my problem.
SELECT NAME FROM Table1 where DATE between 20151216 and 20151217 intersect SELECT NAME FROM Table1 where DATE between 20151217 and 20151218
How does elasticsearch to find the intersection of two search results like mysql?

Elasticsearch aggregations filtered result is not working properly

two sample documents
POST /aggstest/test/1
{
"categories": [
{
"type": "book",
"words": [
{"word":"storm","count":277},
{"word":"pooh","count":229}
]
},
{
"type": "magazine",
"words": [
{"word":"vibe","count":100},
{"word":"sunny","count":50}
]
}
]
}
POST /aggstest/test/2
{
"categories": [
{
"type": "book",
"words": [
{"word":"rain","count":160},
{"word":"jurassic park","count":150}
]
},
{
"type": "megazine",
"words": [
{"word":"tech","count":200},
{"word":"homes","count":30}
]
}
]
}
aggs query
GET /aggstest/test/_search
{
"size": 0,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"categories.type": "book"
}
},
{
"term": {
"categories.words.word": "storm"
}
}
]
}
}
}
},
"aggs": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"categories.type": "book"
}
}
]
}
},
"aggs": {
"book_category": {
"terms": {
"field": "categories.words.word",
"size": 10
}
}
}
}
},
"post_filter": {
"term": {
"categories.type": "book"
}
}
}
result
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0,
"hits": []
},
"aggregations": {
"filtered": {
"doc_count": 1,
"book_category": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "pooh",
"doc_count": 1
},
{
"key": "storm",
"doc_count": 1
},
{
"key": "sunny",
"doc_count": 1
},
{
"key": "vibe",
"doc_count": 1
}
]
}
}
}
}
========================
Expected aggs result set should not include "sunny" and "vibe" because it's "magazine" type.
I used filter query and post_filter, but I couldn't get only "book" type aggs result.
All the filters you apply (in-query and in-aggregation) still return the whole categories document. And this document, which contains all 4 words, is a scope for aggregation. Hence you always get all 4 buckets.
As far as I understand, some way to manipulate buckets on server-side would be introduced with reducers in version 2.0 of Elasticsearch.
What you may use now is changing the mapping so that categories is nested object. Hence you'll be able to query them independently and aggregate accordingly using nested aggregation. Changing object type to nested requires reindexing.
Also please note that post-filters are not applied to aggregation whatsoever. They are used to filter the original query without affecting the aggregation when you need to aggregate on wider scope than returned hits.
And one more thing, if you already have filter in query there's no need to put it in aggregation, scope is already filtered.