How to write custom Elasticsearch Query in Java? - java

This is my query on Elasticsearch,
GET index101/_search
{
"query": {
"function_score": {
"boost_mode": "replace",
"query": {
"constant_score": {
"filter": {
"terms": {
"fields": ["767","434", "101", "222"]
}
}
}
},
"pqcode_score": {
"descriptors": [
{
"descriptor": "base64string"
}
],
"pqparams": {
"bucket_field": "fields",
"pqcode_field": "fields2",
"distance_function": "similarity",
"model": "random"
}
}
}
}
}
Looked into the documentation of Elasticsearch with Java, but couldn't find anything that could resolve this query in Java.
I created a JSON file, and got the input query in the jsonObject and then passed it as a parameter to searchSourceBuilder.query().
But it gives the error that the jsonObject can't be converted into QueryBuilder.
How can we go ahead with this query in Java?
Is there any other workaround for this?

looks like pqcode_score is your custom key in the Elasticsearch query, and you are trying to add the custom component/constructs in your Elasticsearch query thats not possible, hence you are getting the error.
You need to use the constructs in your Elasticsearch query thats supported by Elasticsearch.

Related

How to do Elasticsearch range query the summation of two fields in Java API?

I have two fields in my documents: ACount and BCount, I want to write a range query to get the documents where sum(ACount + BCount) > 100 through Java API. I was trying to do something like
BoolQueryBuilder.must(QueryBuilders.rangeQuery(...).gte(100)), but couldn't find a good way to do it. Does anyone know how to do this?
You need to use painless script for this.
{
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"source": "(doc['ACount'].value + doc['BCount'].value) > params.count",
"params": {
"count": 100
}
}
}
}
]
}
}
}
You can use java client generate the above query.

Elastic search exact match query issue

I am having a problem while querying elastic search. The below is my query
GET _search {
"query": {
"bool": {
"must": [{
"match": {
"name": "SomeName"
}
},
{
"match": {
"type": "SomeType"
}
},
{
"match": {
"productId": "ff134be8-10fc-4461-b620-79s51199c7qb"
}
},
{
"range": {
"request_date": {
"from": "2018-08-22T12:16:37,392",
"to": "2018-08-28T12:17:41,137",
"format": "YYYY-MM-dd'T'HH:mm:ss,SSS"
}
}
}
]
}
}
}
I am using three match queries and a range query in the bool query. My intention is getting docs with these exact matches and with in this date range. Here , if i change name and type value, i wont get the results. But for productId , if i put just ff134be8, i would get results. Anyone knows why is that ? . The exact match works on name and type but not for productId
You need to set the mapping of your productId to keyword to avoid the tokenization. With the standard tokenizer "ff134be8-10fc-4461-b620-79s51199c7qb" will create ["ff134be8", "10fc", "4461", "b620", "79s51199c7qb"] as tokens.
You have different options :
1/ use a term query to check without analyzing the content of the field
...
{
"term": {
"productId": "ff134be8-10fc-4461-b620-79s51199c7qb"
}
},
...
2/ if you are in Elasticsearch 6.X you could change your request to
...
{
"match": {
"productId.keyword": "ff134be8-10fc-4461-b620-79s51199c7qb"
}
},
...
As elasticsearch will create a subfield keyword with the type keyword for all string field
The best option is, of course, the first one. Always use term query if you are trying to match the exact content.

Not able to build query for Elasticsearch using java api

Am trying to query elasticsearch via java api for the below elasticsearch query
get my_index12/_search {
"query" : {
"bool": {
"must": [
{
"match": {
"code": {
"query": "TE-7000-8002-W",
"operator": "and"
}
}
},
{
"match": {
"locale": {
"query": "en_US",
"operator": "and"
}
}
}
]
}
}
}
The above query is working fine is Kibana. Am trying to replicate the same query using Elasticsearch Java API.
Please find my JAVA API query that am trying to build.
QueryBuilder qb = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("code",name)).operator(Operator.AND);
Am getting the below error from eclipse.
The method operator(Operator) is undefined for the type BoolQueryBuilder
Am using Elasticsearch 6.2.3 version
In java transport client, search request can be build both in QueryBuilders and XContent format which build query param in json format.
With QueryBuilder, especially BoolQuery, the operator in query dsl is represented by either must() (means and operator) or should() (means or operator).
As described, your query can be represented like:
QueryBuilders.boolQuery().must().must().build();
One more interesting question is how to present the following query DSL:
{
"query": {
"bool": {
"must": [{
"term": {
"field1": "value"
}
}, {
"match": {
"filed2": "value"
}
}],
"should": [{
"term": {
"field3": "value"
}
},{
"term": {
"field4": "value"
}]
}
}
}
once you can understand the demo query DSL and successfully implement it with java API, means you are getting to know Java Transport client API.
hope can offer you some help

Querying ElasticSearch using a JSON file through JAVA API

I have a query in valid JSON format which works well in kibana or Sense when I use GET request.I am also able to create this query using XContentBuilder, but I need to send this query using its JSON form as it is to ElasticSearch. Is it possible to store the query in a JSON file and query ElasticSearch using this JSON file.
My query -
{
"min_score":5,
"sort" : [
{
"_geo_distance" : {
"location" : [40.715, -73.988],
"order" : "asc",
"unit" : "km",
"mode" : "min",
"distance_type" : "arc"
}
}
],
"query": {
"bool": {
"must": {
"query_string": {
"query": "hospital",
"analyzer": "english"
}
},
"filter": {
"geo_distance": {
"distance": "50000km",
"location": {
"lat": 40.715,
"lon": -73.988
}
}
}
}
}
}
What I want is to store this query in a JSON file and use this JSON file to send a search request directly without using Query builder.
You can use a search template, and store this template in the cluster state, see the official documentation about search templates, especially about pre-registered templates.

ElasticSearch 2.0 Java API aggregate filter with query_string

Running on ElasticSearch 2.0 connecting via the Java API. I've got the following query working via the REST API and can't figure out how to do this using the Java API.
{
"query": {
"query_string": {
"query": "myfield:*"
}
},
"aggs" : {
"foo_low": {
"filter" : {
"query" : {
"query_string" : {
"query": "myfield:[1 TO 5]"
}
}
}
},
"foo_high": {
"filter" : {
"query" : {
"query_string" : {
"query": "myfield:[6 TO 10]"
}
}
}
}
}
}
I've had a look at the examples using the addAggregation method but not sure how to pass in the query_string part.
As a bit of a background, was originally using Solr so have multiple Solr facet queries that need to be translated to ElasticSearch. The facet queries are a bit more complicated then I've shown in the example, with multiple fields and conditions referenced in each Solr facet query which is why I want to use the Lucene query with query_string.
Any ideas gratefully received! Thanks.
Since it looks like myfield is an integer field, you could use a range filter instead of a query_string which is more intended for text matching. Since you have two ranges you're interested in, I suggest to use the range aggregation which allows you to define several range buckets (note that the to parameter is not included in the range). Your query would then go like this:
{
"query": {
"query_string": {
"query": "myfield:*"
}
},
"aggs": {
"high_low": {
"range": {
"field": "myfield",
"keyed": true,
"ranges": [
{
"key": "foo_low",
"from": 1,
"to": 6
},
{
"key": "foo_high",
"from": 6,
"to": 11
}
]
}
}
}
}
Translated into Java code, it goes like this:
// 1. bootstrap the query
SearchRequestBuilder search = node.client().prepareSearch()
.setSize(0).setFrom(0)
.setQuery(QueryBuilders.queryStringQuery("myfield:*"));
// 2. create the range aggregation
RangeBuilder rangeAgg = AggregationBuilders.range("high_low").field("myfield");
rangeAgg.addRange("foo_low", 1, 6);
rangeAgg.addRange("foo_high", 6, 11);
search.addAggregation(rangeAgg);
// 3. execute the query
SearchResponse response = search.execute().actionGet();
** UPDATE **
As requested, here is the Java code that will generate the exact query you posted:
// 1. bootstrap the query
SearchRequestBuilder search = node.client().prepareSearch()
.setSize(0).setFrom(0)
.setQuery(QueryBuilders.queryStringQuery("myfield:*"));
// 2. create the filter aggregations
FilterAggregationBuilder lowAgg = AggregationBuilders
.filter("foo_low")
.filter(QueryBuilders.queryStringQuery("myfield:[1 TO 5]"));
search.addAggregation(lowAgg);
FilterAggregationBuilder highAgg = AggregationBuilders
.filter("foo_high")
.filter(QueryBuilders.queryStringQuery("myfield:[6 TO 10]"));
search.addAggregation(highAgg);
// 3. execute the query
SearchResponse response = search.execute().actionGet();

Categories

Resources