Elasticsearch - get source field data with java api - elasticsearch

I'm using elastic search with jest (as java client).
I need some fields that is in nested document and since cannot get nested fields as pair, I need '_source' to get them.
Here is previous question to get them in ES query[ Link ], and It works well.
BUT cannot convert its query as jest code.
Below is my try.
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(
query
)
.fields( // need _source but no method.
"oid",
"_source.events.activityoid",
"_source.events.worktime");

Try using fetchSource() like this:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(query)
.fetchSource(new String[] {
"oid",
"events.activityoid",
"events.worktime"
}, null);

Related

Elastic search duplicate aggregation section in a query with NEST

I am creating a simple elastic request with Nest.
var searchRequest = new SearchRequest()
{
Aggregations = new AggregationDictionary()
{
}
};
When I serialize the query with elasticClient.RequestResponseSerializer.SerializeToString(searchRequest the query I am seeing like this :
{"aggs":{},"aggregations":{}}
Aggregation sections were created two times.
What should I do?
Is this a problem?
My nest version and elastic Search version are 7.6.2
Thanks.

ElasticSearch RestHighLevelClient provides inaccurate results

I am using ES with SpringBoot. I try to search results using the following code snippet.
SearchRequest searchRequest = new SearchRequest("businesses");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("name", "Microsoft"));
SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] searchHit = response.getHits().getHits();
When I iterate through "searchHits", none of the names matches "Microsoft". It always returns some other names. Also, the list of other names is consistent evrytime. Is anything wrong in the code?
The type of the name field should be keyword in your document mapping. I guess you didn't set it explicitly and by default it is set to text.

Unable to fetch the data with help of QueryBuilders.termQuery

I am a newcomer to elastic search I was trying to work with high-level Rest Client
I am able to work with CRUD operations, With Search functionality, I got stuck up.
My objective to bring all the data based on the book id start with E106 search criteria
http://localhost:5918/book-elastic/books/book/E106
I added the part of the code below
I am able to get all the data using
QueryBuilders.matchAllQuery()
But I couldn't get a specific field value
QueryBuilders.termQuery("_id",bookId)
I have also shared the screenshot of the both results
Can somebody help me out on the query?
Kindly revert in case of any further information needed.
Thanks in Advance
public Page<BookEntity> findByBookId(String bookId, Pageable pageable) throws IOException{
SearchRequest searchRequest = new SearchRequest(INDEX);
searchRequest.types(TYPE);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.fetchSource(false);
//searchSourceBuilder.fetchSource(null, new String[]{"excludedProperty"});
/*MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("id",bookId);
matchQueryBuilder.fuzziness(Fuzziness.AUTO);
matchQueryBuilder.prefixLength(3);
matchQueryBuilder.maxExpansions(7);*/
searchSourceBuilder.from((int)pageable.getOffset());
searchSourceBuilder.size(pageable.getPageSize());
//searchSourceBuilder.query(matchQueryBuilder);
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//searchSourceBuilder.query(QueryBuilders.termQuery("_id",bookId));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
SearchHit[] objectHits = hits.getHits();
for (SearchHit searchHit : objectHits) {
System.out.println("***************************");
System.out.println("Search Hit :: "+searchHit);
System.out.println("***************************");
}
return null;
}
Result Screenshot
matchAllQuery
Input : {"from":0,"size":20,"query":{"match_all":{"boost":1.0}},"_source":false}
Response
Response Value: {"took":5,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"bookdata","_type":"books","_id":"E106401","_score":1.0},{"_index":"bookdata","_type":"books","_id":"E106403","_score":1.0},{"_index":"bookdata","_type":"books","_id":"E10640","_score":1.0}]}}
Input Values: QueryBuilders.termQuery("_id",bookId)
{"from":0,"size":20,"query":{"term":{"_id":{"value":"E106","boost":1.0}}},"_source":false}
Response
The Response is Null
matchPhrasePrefixQuery from QueryBuilders solved my issues

elasticsearch NEST : get TopHits result directly without using bucket.TopHits()

With nest I am doing a Terms aggregation .
I am also doing an inner TopHits aggregation .
My result give me all results infos in the response object except TopHits values which i can read thanks to TopHits() method.
I would like to have tophits values directly in result without using NEST TopHits() methode for reading into aggs. I would like to have all datas in info as we have in elastic search classic requests.
This is what i am actually doing :
My aggregation request:
var response = Client.Search<myclass>(s => s
.Type("type")
.Aggregations(a => a
.Terms("code_bucket", t => t
.Field("field_of_aggregation")
.Size(30)
.Order(TermsOrder.CountAscending)
.Aggregations(a2 => a2
.TopHits("code_bucket_top_hits", th => th.Size(20))
)
)));
I receive a result object in wich i can access all infos except TopHits.
if we examine results we can see TopHits values are stored in private field "_hits":
If I stringify result object , i can see the total number of TopHits, but I can't see the field _hits so i can see the documents:
JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(response);
json does not contains topHits result:
I can access to values but i need to use nest method TopHits():
var firstBucket= response.Aggs.Terms("code_bucket");
foreach (var bucket in firstBucket.Buckets)
{
var hits = bucket.TopHits("code_bucket_top_hits");
foreach (var hit in hits.Documents<myclass>())
{
var prop1= hit.prop1;
var prop2= hit.prop2;
}
}
}
But it would be really usefule if i could have all infos in one , like we have when we do elasticsearch request without nest
Do you know if there is a way?
NEST is a higher level abstraction over Elasticsearch that models each request and response with strong types, providing fluent and object initializer syntaxes to build requests, and methods to access portions of the response, without having to handle JSON serialization yourself.
Sometimes however, you might want to manage this yourself, which is what it sounds like you'd like to do. In these cases, Elasticsearch.Net can be used, which is a low level client for Elasticsearch and is unopinionated in how you model your requests and responses.
You can use the client in Elasticsearch.Net instead of NEST, however, the good news is NEST uses Elasticsearch.Net under the covers and also exposes the low level client through the .LowLevel property on IElasticClient. Why would you want to use the lowlevel client on NEST as opposed to just using Elasticsearch.Net directly? A major reason to do so is that you can take advantage of strong types for requests and responses when you need to and leverage NEST's usage of Json.NET for serialization, but bypass this and make calls with the low level client when you want/need to.
Here's an example
var client = new ElasticClient();
var searchRequest = new SearchRequest<Question>
{
Size = 0,
Aggregations = new TermsAggregation("top_tags")
{
Field = "tags",
Size = 30,
Order = new[] { TermsOrder.CountAscending },
Aggregations = new TopHitsAggregation("top_tag_hits")
{
Size = 20
}
}
};
var searchResponse = client.LowLevel.Search<JObject>("posts", "question", searchRequest);
// this will be of type JObject. Do something with it
searchResponse.Body
Here, I can use NEST's object initializer syntax to construct a request, but use the low level client to deserialize the response to a Json.NET JObject. You can deserialize to a T of your choosing by changing it in client.LowLevel.Search<T>(). You could for example use
var searchResponse = client.LowLevel.Search<string>("posts", "question", searchRequest);
to return a string, or
var searchResponse = client.LowLevel.Search<Stream>("posts", "question", searchRequest);
to return a stream, etc.

NEST ElasticSearch, Query Result Is Empty

I'm trying to query an elastic search index using a match_all query.
Uri uri = new Uri("http://10.10.10.67:9200");
ConnectionSettings connection = new ConnectionSettings(uri);
connection.SetDefaultIndex("leases");
int port = connection.Port;
ElasticClient client = new ElasticClient(connection);
var feeQueryObject = client.Search<FeeQueryResult>(s => s
.Type("leases").MatchAll());
Using sense, I get results but not with NEST.
Not sure if I have to set up my mapped class exactly how the schema is in the ElasticSearch document? - I only have a few properties in my class, not all of them.
Any ideas as to why there are no results returned?
This was my fault.
The type was incorrect. Should be 'fee' not 'leases'.

Resources