Spring data elasticsearchQuery equivalent to HasChildQuery - spring-boot

{
"query": {
"bool": {
"must": [
{
"match": {
"Id": "xxxxxx"
}
},
{
"has_child": {
"type": "component",
"query": {
"bool": {
"should": [
{
"term": {
"type": "xxxxx"
}
},
{
"term": {
"name": "xxxxx"
}
}
]
}
},
"inner_hits": {}
}
}
]
}
}
}
Want to replace above Query using Criteria or NativeSearchQueryBuilder. I have tried following its and hanging on search for long time.
QueryBuilder parentQuery = QueryBuilders.matchQuery("Id", Id);
HasChildQueryBuilder childQuery = JoinQueryBuilders.hasChildQuery("component",
QueryBuilders.termQuery("type","xxxxx"), ScoreMode.None);
HasChildQueryBuilder childQuery2 = JoinQueryBuilders.hasChildQuery("component",
QueryBuilders.termQuery("name","xxxxx"), ScoreMode.None);
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(parentQuery)
.withQuery(childQuery).withQuery(childQuery2).build();
SearchHits<ENTITY> recipeSearchHits= elasticsearchOperations.search(query, ENTITY.class);
Followed official spring data document https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.jointype but i am doing something wrong here so its going on loop.

Related

Sql query on elastic 6.8 does not work as expected. Array of nested objects are flattened same as of type object

Thanks for the answer in advance.
I am running a query
SELECT key
FROM records_index
WHERE
(product_nested_field.code = '1234' and product_nested_field.codeset = 'category1' OR product_nested_field.code = '444' and product_nested_field.codeset = 'category1')
AND (role_name IN ('user', 'admin'))
GROUP BY records_uuid
In records_index I have record with two products
[
{codeset: category1, code:444},
{codeset: category2, code:1234}
]
The problem is that query does find a specified record.
such behavior is expected for "type": "object" but why I am getting that result for product_nested_field of type nested?
when I translate SQL to JSON I am getting
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"nested": {
"query": {
"term": {
"product_nested_field.codeset": {
"value": "category1"
}
}
}
}
}
]
}
},
{
"bool": {
"must": [
{
"bool": {
"should": [
{
"nested": {
"query": {
"term": {
"product_nested_field.code": {
"value": "1234"
}
}
}
}
},
{
"nested": {
"query": {
"term": {
"product_nested_field.code": {
"value": "444"
}
}
}
}
}
]
}
}
]
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
}
why elastic moves product_nested_field.codeset = 'category1' into separate nested query.

Replace OR filtered query in elasticsearch while upgrading to elastic-search 5

I am trying to upgrade elastic-search to version 5. Previously I was using elastic-search version 2. I am having hard time converting OR query to bool[:should] query. Here is how my query looks like that was working in ES-2.
query: {:bool=>{
:should=>[
{:term=>{:user=>{:term=>70890}}},
{:term=>{:assignee=>{:term=>70890}}},
{:term=>{:participant=>{:term=>70890}}}],
:minimum_number_should_match=>1,
:filter=>[{:bool=> {:must_not=>{:exists=>{:field=>:date}}}},
{:term=>{:deleted=>false}},
{:or=>{:filters=>[
{:term=>{:user=>70890}},
{:term=>{:assignee=>70890}},
{:term=>{:private=>false}}
]}
}
]
}}
Query:
{
"bool": {
"should": [
{
"term": {
"user": {
"term": 70890
}
},
{
"term": {
"assignee": {
"term": 70890
}
}
},
{
"term": {
"participant": {
"term": 70890
}
}
}
],
"minimum_number_should_match": 1,
"filter": [
{
"bool": {
"must_not": {
"exists": {
"field": "date"
}
}
}
},
{
"term": {
"deleted": false
}
},
{
"or": {
"filters": [
{
"term": {
"user": 70890
}
},
{
"term": {
"assignee": 70890
}
},
{
"term": {
"private": false
}
}
]
}
}
]
}
}
I want to replace {:or=>{:filters}}. I have tried moving this part in :bool[:should] query but it gives wrong results.
q[:bool][:should] << {term: {user: 70890}}
q[:bool][:should] << {term: {assignee: 70890}}
q[:bool][:should] << {term: {private: false}}
q[:bool][:minimum_should_match] = 1
When I change minimum_should_match=2 it changes results. How do I fix it?

Is there any good boolean query parser for ElasticSearch?

Is there any library in ElasticSearch or other open-source, that transforms the boolean query into a ElasticSearch query?
With the typical boolean query expressions (AND, OR, "", *, ?) to transform into the "json" query for ElasticSearch and create the "musts", "shoulds", etc...
I mean, for example, to transform this:
(city = 'New York' AND state = 'NY') AND ((businessName='Java' and businessName='Shop') OR (category='Java' and category = 'Shop'))
into this:
{
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"city": "New york"
}
},
{
"term": {
"state": "NY"
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"businessName": "Java"
}
},
{
"term": {
"businessName": "Shop"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"category": "Java"
}
},
{
"term": {
"category": "Shop"
}
}
]
}
}
]
}
}
]
}
}
}
There's a Python library called luqum that does exactly what you need.
That library will parse the Lucene expression into an abstract syntax tree. You can then use that tree and generate the Elasticsearch JSON DSL equivalent query.

How to improve inner_hits in Elasticsearch

I have two ES_TYPEs in my_index
user
user_property
One is defined as parent (user) and another as child (user_property)
user_property has following mapping:
PUT /my_index/_mapping/user_property
{
"user_property": {
"properties": {
"name": {
"type": "keyword",
},
"value": {
"type": "keyword"
}
}
}
}
I want to get all users having some properties (say property1, property2) along with their properties value, so to do this I create following query with inner_hits but query response time is exponentially large with inner_hits.
GET /my_index/user/_search
{
"query": {
"bool": {
"must": [
{
"has_child": {
"type": "user_property",
"query": {
"bool": {
"must": [
{
"term": {
"name": "property1"
}
}
]
}
},
"inner_hits": {
"name": "inner_hits_1"
}
}
},
{
"has_child": {
"type": "user_property",
"query": {
"bool": {
"must": [
{
"term": {
"name": "property2"
}
}
]
}
},
"inner_hits": {
"name": "inner_hits_2"
}
}
}
]
}
}
}
Is there any way to reduce this time ?

How to combine multiple bool queries in elasticsearch

I want to create the equivalent of the following query -
(city = 'New York' AND state = 'NY') AND ((businessName='Java' and businessName='Shop') OR (category='Java' and category = 'Shop'))
I tried different combinations of bool queries using must and should but nothing seems to be working. Can this be done?
How about something like this:
{
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"city": "New york"
}
},
{
"term": {
"state": "NY"
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"businessName": "Java"
}
},
{
"term": {
"businessName": "Shop"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"category": "Java"
}
},
{
"term": {
"category": "Shop"
}
}
]
}
}
]
}
}
]
}
}
}

Resources