elasticsearch aggs groupby field and orderby score - java

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);

Related

query data from elasticsearch using java highlevelrestclient

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

Combination of script score and function score filter in java api

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

ElasticSearch - matchPhraseQuery API to search with multiple fields

Am searching for specific field which is having ngram tokenizer and am querying that field (code) using matchPhraseQuery and it is working fine.
Now, i want to search with 3 field. How can we do this.?
Please find my java code which am searching for only one field (code).
SearchRequest searchRequest = new SearchRequest(INDEX);
searchRequest.types(TYPE);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
QueryBuilder qb = QueryBuilders.matchPhraseQuery("code", code);
searchSourceBuilder.query(qb);
searchSourceBuilder.size(10);
searchRequest.source(searchSourceBuilder);
Please find my mappings details below :
PUT products
{
"settings": {
"analysis": {
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "ngram",
"char_filter": [
"html_strip"
],
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"doc": {
"properties": {
"code": {
"type": "text",
"analyzer": "custom_analyzer"
},
"attribute" : {
"type" : "text",
"analyzer" : "custom_analyzer"
},
"term" : {
"type" : "text",
"analyzer" : "custom_analyzer"
}
}
}
}
}
Now, i want to make a search query for 3 fields code, attribute, term
I have tried the below java code, which is not working as expected :
BoolQueryBuilder orQuery = QueryBuilders.boolQuery();
QueryBuilder qb1 = QueryBuilders.matchPhraseQuery("catalog_keywords", keyword);
QueryBuilder qb2 = QueryBuilders.matchPhraseQuery("product_keywords", keyword);
orQuery.should(qb1);
orQuery.should(qb2);
orQuery.minimumShouldMatch(1);
searchSourceBuilder.query(orQuery);
searchSourceBuilder.size(10);
searchRequest.source(searchSourceBuilder);
My Input Query :
Logi
Output am getting like :
"MateriaƂy, programy doborowe | Marketing | Katalogi, broszury"
Which is totally irrelavant to my query. Expected results is, Logiciels
And my field having value with delimiters |, so i just want only the exact match of the word/character. It should not print with all the delimiters and all.
Use bool query :
GET products/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"FIELD": "PHRASE"
}
},
{
"match_phrase": {
"FIELD": "PHRASE"
}
},
{
"match_phrase": {
"FIELD": "PHRASE"
}
}
]
}
}
}

ElasticSearch - JavaApi searching by each character instead of term (word)

Am fetching documents from elastic search using java api, i have the following code in my elastic search documents and am trying to search it with the following pattern.
code : MS-VMA1615-0D
Input : MS-VMA1615-0D -- Am getting the results (MS-VMA1615-0D).
Input : VMA1615 -- Am getting the results (MS-VMA1615-0D) .
Input : VMA -- Am getting the results (MS-VMA1615-0D) .
But, if i give input like below, am not getting results.
Input : V -- Am not getting the results.
INPUT : MS -- Am not getting the results.
INPUT : -V -- Am not getting the results.
INPUT : 615 -- Am not getting the results.
Am expecting to return the code MS-VMA1615-0D. In simple, am trying to search character by character instead of term (word).
It should not return the code MS-VMA1615-0D for the following cases, Because its not matching with my code.
Input : VK -- should not return the results.
INPUT : MS3 -- should not return the results.
Please find my below java code that am using
private final String INDEX = "products";
private final String TYPE = "doc";
SearchRequest searchRequest = new SearchRequest(INDEX);
searchRequest.types(TYPE);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
QueryStringQueryBuilder qsQueryBuilder = new QueryStringQueryBuilder(code);
qsQueryBuilder.defaultField("code");
searchSourceBuilder.query(qsQueryBuilder);
searchSourceBuilder.size(50);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = null;
try {
searchResponse = SearchEngineClient.getInstance().search(searchRequest);
} catch (IOException e) {
e.getLocalizedMessage();
}
Item item = null;
SearchHit[] searchHits = searchResponse.getHits().getHits();
Please find my mapping details :
PUT products
{
"settings": {
"analysis": {
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "my_pattern_tokenizer",
"char_filter": [
"html_strip"
],
"filter": [
"lowercase",
"asciifolding"
]
}
},
"tokenizer": {
"my_pattern_tokenizer": {
"type": "pattern",
"pattern": "-|\\d"
}
}
}
},
"mappings": {
"doc": {
"properties": {
"code": {
"type": "text",
"analyzer": "custom_analyzer"
}
}
}
}
}
After Update with new Answer :
This is my request via Java API
'SearchRequest{searchType=QUERY_THEN_FETCH, indices=[products], indicesOptions=IndicesOptions[id=38, ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false], types=[doc], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=128, source={"size":50,"query":{"match_phrase":{"code":{"query":"1615","slop":0,"boost":1.0}}}}}
' . But am getting response as null
Follow up: ElasticSearch - JavaApi searching not happening without (*) in my input query
Your mapping should look like:
PUT products
{
"settings": {
"analysis": {
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "ngram",
"char_filter": [
"html_strip"
],
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"doc": {
"properties": {
"code": {
"type": "text",
"analyzer": "custom_analyzer"
}
}
}
}
}
And you should be using a match_phrase query.
In Kibana:
GET products/_search
{
"query": {
"match_phrase": {
"code": "V"
}
}
}
will return the result:
"hits": [
{
"_index": "products",
"_type": "doc",
"_id": "EoGtdGQBqdof7JidJkM_",
"_score": 0.2876821,
"_source": {
"code": "MS-VMA1615-0D"
}
}
]
But this:
GET products/_search
{
"query": {
"match_phrase": {
"code": "VK"
}
}
}
wont:
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
Based on your comment:
Instead of using a Query string:
QueryStringQueryBuilder qsQueryBuilder = new QueryStringQueryBuilder(code);
qsQueryBuilder.defaultField("code");
searchSourceBuilder.query(qsQueryBuilder);
searchSourceBuilder.size(50);
searchRequest.source(searchSourceBuilder);
Use a match phrase query:
QueryBuilder query = QueryBuilders.matchPhraseQuery("code", code);
searchSourceBuilder.query(query);
searchSourceBuilder.size(50);
searchRequest.source(searchSourceBuilder);

ElasticSearch stored_fields java API

I am trying to build ElasticSearch query using java API. This query uses stored_fields, can anyone please help me how to build stored_field query from java code.
{
"from": 0,
"size": 10,
"stored_fields": [
"f1",
"f2",
"f3",
"f4"
],
"query": {
"bool": {
"must": {
"match": {
"compositeField1": {
"query": "test123",
"type": "boolean",
"operator": "AND"
}
}
}
},
"sort": [
{
"_score": {}
}
]
}
Code following
SearchRequestBuilder srb = ....
srb.setFrom(0).setSize(10).storedFields("f1", "f2", "f3", "f4");
srb.addSort(SortBuilders.scoreSort());
BoolQueryBuilder bqb = new BoolQueryBuilder();
bqb.must(QueryBuilders.matchQuery("compositeField1", "test123")
.operator(Operator.AND).type(MatchQuery.Type.BOOLEAN));
srb.setQuery(bqb);
Note: ES set some default required parameters.

Categories

Resources