Array search in elasticsearch - java

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"]
}
}
}

Related

Elasticsearch SELECT * FROM IP="1.1.1.1" AND NAME="ETH1/10"

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"
}
}
]
}
}
}
}

How to write query to find percentage in elasticsearch?

I have data in elasticsearch.
this is my actual doc https://docs.google.com/document/d/1DKID90I9ulUcut-S8UfrnSjY-3citEwmyfnJJmrIRU8/edit?usp=sharing
doc:
{
store_id:"abc",
event_timestamp:"2019-06-05 13:00:05",
event_type:"heartbeat"
}
I have store_id, range of dates and event type in the input.in output, I need the percentage amount of time device was online for that hour.
This is how we consider device online.
If there is an event="heartbeat" for a store_id in an hour then we say the store is online.
example 1.
so if the range is of "2019-05-07" to "2019-05-08" and there are 14 docs with different hour then the percentage will be (14/(2*24))*100
example 2.
doc:
{
store_id:"abc",
event_timestamp:"2019-06-05 13:00:05",
event_type:"heartbeat"
}
doc:
{
store_id:"abc",
event_timestamp:"2019-06-05 14:00:05",
event_type:"heartbeat"
}
doc:
{
store_id:"abc",
event_timestamp:"2019-06-05 14:00:05",
event_type:"heartbeat"
}
if input was store_id="abc" and date_range="2019-06-05" to ""2019-06-05" and event_type="heartbeat" then output would be (2/(1*24)) because there are only two different hour with event=heartbeat of that store.
this is my query for the cumulative sum.If some How I can divide the final cumulative sum with difference between dates.
GET /internship38/_search
{
"query":
{
"bool":
{
"must":
[
{
"match" :
{
"attributes.store_id" : "41b15888-0c2f-48f9-89d0-dc7aad19f52b"
}
},
{
"match":
{
"event_type":"app_sent_heartbeat"
}
}
]
}
},
"aggs":
{
"my_date_histo":{
"date_histogram":{
"field":"arrival_timestamp",
"interval":"day"
},
"aggs":
{
"distinct_hours": {
"cardinality": {
"script": {
"lang": "painless",
"source": "doc[params.date_field].value.hourOfDay;",
"params": {
"date_field": "arrival_timestamp"
}
}
}
},
"cumulative_hours": {
"cumulative_sum": {
"buckets_path": "distinct_hours"
}
}
}
}
}
}
Can It be done in java? for example https://www.programcreek.com/java-api-examples/?api=org.elasticsearch.script.Script
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-script-aggregation.html
Above link in the elasticsearch documentation would help if you can reformat your query into "buckets" using the "aggs" functionality.
from link:
{
"size": 0,
"aggs" : {
"sales_per_month" : {
"date_histogram" : {
"field" : "date",
"calendar_interval" : "month"
},
"aggs": {
"total_sales": {
"sum": {
"field": "price"
}
},
"t-shirts": {
"filter": {
"term": {
"type": "t-shirt"
}
},
"aggs": {
"sales": {
"sum": {
"field": "price"
}
}
}
},
"t-shirt-percentage": {
"bucket_script": {
"buckets_path": {
"tShirtSales": "t-shirts>sales",
"totalSales": "total_sales"
},
"script": "params.tShirtSales / params.totalSales * 100"
}
}
}
}
}
}

building compound query in elasticsearch

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,

How to merge geo distance filter with bool term query

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
}
}
}
}
}

Elasticsearch postfiler cancel filter

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

Categories