I try to find out how to build the following query with elasticsearch java api
{
"query": {
"bool": {
"must": [
{
"terms_set": {
"names": {
"minimum_should_match_field": "some_match_field",
"terms": [
"Ala",
"Bob"
]
}
}
}
]
}
}
}
I tried to build this query with following code, but there is no termsSetQuery method as well as minimumShouldMatchField in api.
NativeSearchQuery build = new NativeSearchQueryBuilder()
.withQuery(boolQuery()
.must(termsQuery("names", List.of("Ala", "Bob"))))
.build();
but it results as below
{
"bool": {
"must": [
{
"terms": {
"names": [
"Ala",
"Bob"
]
}
}
]
}
}
You need to use TermsSetQueryBuilder for creating query like below:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
List<String> terms = new ArrayList<>();
terms.add("Ala");
searchSourceBuilder.query(QueryBuilders.boolQuery()
.must(new TermsSetQueryBuilder("names", terms).setMinimumShouldMatchField("some_match_field")));
Related
How to query data from elasticsearch based on the property that is present inside the actual object.
Format of data stored in elsticsearch:
{
"principals": [
{
"id": 1,
"account": {
"account_id": 2
}
}
]
}
Search query in postman:
{
"query": {
"terms": {
"account_id": [
1
]
}
}
}
This is returning the required result in postman.
How to achieve the same in java using highlevelrestclient.
I am not sure how your above search query worked in fetching corresponding document.
But I had indexed and searched your document through this way :
mapping:
{
"mappings": {
"properties": {
"principals": {
"properties": {
"id": { "type": "integer" },
"account": {
"properties": {
"account_id": { "type": "integer" }
}
}
}
}
}
}
}
search query:
{
"query": {
"terms": {
"principals.account.account_id": [2]
}
}
}
Search result :
"hits": [
{
"_index": "nestedindex",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"principals": [
{
"id": 1,
"account": {
"account_id": 2
}
}
]
}
}
]
Search query through Elasticsearch Resthighlevelclient
SearchRequest searchRequest = new SearchRequest("testIndex"); //in place of "testIndex" you can give your index name
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
List<Integer> accountIds = new ArrayList<Integer>();
accountIds.add(2);
sourceBuilder.query(QueryBuilders.termsQuery("principals.account.account_id", accountIds));
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse =
client.search(searchRequest, RequestOptions.DEFAULT); //client is ES client
return searchResponse; //you can read your hits through searchResponse.getHits().getHits()
ElasticSearch client can be instantiated in spring-boot application by creating configuration file in your project and autowiring the client where required:
#Configuration
#Primary
public class ElasticsearchConfig {
private RestHighLevelClient restHighLevelClient;
#Bean(destroyMethod = "close")
public RestHighLevelClient client() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
return client;
}
Im building a filter function and what I want is a wildcard filter. If value is "roj", all records in any field containing "roj" should be displayed.
How to implement this?
Here's my query,
{
"query": {
"bool": {
"must": [
{
"exists": {
"field": "Project_error"
}
},
{
"wildcard": {
"api_name": {
"wildcard": "*roj*"
}
}
},
{
"wildcard": {
"error_Code": {
"wildcard": "*roj*"
}
}
}
]
}
}
}
Java code
BoolQueryBuilder bqb = new BoolQueryBuilder();
bqb.must(QueryBuilders.existsQuery("Project_error"))
if(!filter.isEmpty()) {
bqb.filter(QueryBuilders.wildcardQuery(fields[0],"*"+filter+"*"));
bqb.must(QueryBuilders.wildcardQuery(fields[1],"*"+filter+"*"));
...
}
searchSourceBuilder.query(bqb);
This script displays data only if both field contains "roj", which not correct.
Using the Below query you can achieve the result.
GET <index_name>/_search
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "*roj*",
"fields":["field_1", "field_2"]
}
}
]
}
}
}
If you want apply your query term in all fields remove the fields attributes in the above query.!!!
I can't find an option how to combine script score and function score filters in elastic java api.
I have the following query:
GET index/type/_search
{
"query": {
"nested": {
"path": "field",
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"field.name": "NAME"
}
}
]
}
},
"functions": [
{
"filter": {
"match": {
"field.type":"TYPE"
}
},
"weight": 3
},
{
"script_score": {
"script":"doc['field.count'].value"
}
}
]
}
}
}
}
}
And tried to write ElasticSearchQuery
ElasticSearchQuery query = new ElasticSearchQuery(Indexes.NAME, Types.TYPE)
.setQueryBuilder(QueryBuilders.nestedQuery(FIELD, QueryBuilders.functionScoreQuery(
QueryBuilders.boolQuery().must(QueryBuilders.matchQuery(FIELD_NAME, fieldName)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.matchQuery(FIELD_TYPE, fieldType),
ScoreFunctionBuilders.weightFactorFunction(3.0F)
)
}), ScoreMode.None));
But how to add script score?
solution is pretty simple:
FunctionScoreQueryBuilder.FilterFunctionBuilder[] filterFunctionBuilders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.matchQuery(FIELD_TYPE, fieldType),
ScoreFunctionBuilders.weightFactorFunction(3)
),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
ScoreFunctionBuilders.scriptFunction(format("doc['%s'].value", FIELD_COUNT))
)
};
currently I implemented it from postman but I can't implement it from JAVA code. Below is the post json body.
I only want to have the full-text search for Innovation. And groupby email and orderby score. But seems the sum of the score still didn't work. Who can help me out? It worked now.
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "Innovation"
}
}
]
}
},
"highlight": {
"require_field_match": false,
"pre_tags" : [ "<b>" ],
"post_tags" : [ "</b>" ],
"order" : "score",
"highlight_filter" : false,
"fields": {
"*": {}
}
},
"aggs": {
"group_by_emails": {
"terms": { "field": "email" }
}
}
}
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
QueryStringQueryBuilder queryString = new QueryStringQueryBuilder(keyword);
searchSourceBuilder.query(queryString);
Script script = new Script("_score;");
AggregationBuilder aggregation = AggregationBuilders
.terms("agg")
.field("email")
.order(BucketOrder.aggregation("sum_score", false))
.subAggregation(AggregationBuilders.sum("sum_score").script(script))
;
searchSourceBuilder.aggregation(aggregation);
System.out.println(searchSourceBuilder.toString());
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(searchSourceBuilder);
I've been working to change my query to a filter in Elasticsearch using the java api. I've made sure that the fields I am running searches on are set to "not_analzed".
Here is the java code for the filter:
FilterBuilder andFilter = FilterBuilders.andFilter(FilterBuilders.termFilter("thread_name", keyword), FilterBuilders.termFilter("site_name", "test_site"));
QueryBuilder filteredQuery = QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), andFilter);
SearchResponse threadResponse = client.prepareSearch("thread_and_messages").setQuery(filteredQuery).setSize(20).setFrom(firstRowOffset).execute().actionGet();
This then gets translated to this in JSON:
"filtered" : {
"query" : {
"match_all" : { }
},
"filter" : {
"and" : {
"filters" : [ {
"term" : {
"thread_name" : "apple"
}
}, {
"term" : {
"site_name" : "test_site"
}
} ]
}
}
}
When I try to do any searches it won't return the document I'm looking for which is thread_name: Apple and site_name: test_site.
Also when I run this using a curl command it won't find that document either.
Can anyone see what I'm doing wrong here?
You can use must clause.That will perform and operation
"query": {
"bool": {
"must": [
{
"query_string": {
"default_field": "thread_name",
"query": "apple"
}
},
{
"query_string": {
"default_field": "site_name",
"query": "test_site"
}
}
]
}
}