matchAllQuery() in ElasticSearch - elasticsearch

matchAllQuery() in Elasticsearch gets me only 10 results how do I increase its output so that I can get as many results as per my requirement.
Code
QueryBuilder query = QueryBuilders.matchAllQuery();

By default 10 results are returned, you need to increase the size parameter:
SearchRequestBuilder request = client.prepareSearch(index)
.setQuery(QueryBuilders.matchAllQuery())
.setSize(100);

Yes u can do , here you can pass aPageRequestcount whatever you want and If you want no of records exist in Elastic search than repository.count() will work for that :-
int aPageRequestcount = (int) repository.count();
NativeSearchQueryBuilder aNativeSearchQueryBuilder = new NativeSearchQueryBuilder();
aNativeSearchQueryBuilder.withIndices(indexName).withTypes(type).withPageable(new PageRequest(0, aPageRequestcount));
final BoolQueryBuilder aQuery = new BoolQueryBuilder();
NativeSearchQuery nativeSearchQuery = aNativeSearchQueryBuilder.withQuery(aQuery).build();
= elasticsearchTemplate.queryForList(nativeSearchQuery, A.class);

Related

Add Size in Elastic NativeSearchQuery

final QueryBuilder contentTagQuery = QueryBuilders.boolQuery()
.filter( QueryBuilders.termQuery("tenantId" , "en"));
SearchHits<Content> searchHits =
elasticsearchOperations.search(
new NativeSearchQuery(contentTagQuery), Content.class,
IndexCoordinates.of("index"));
How can I add size in this query, as I only need the first result.
You can set this on the Query instance:
NativeSearchQuery query = new NativeSearchQuery(contentTagQuery);
query.setMaxResults(1);

Elasticsearch Search Scroll API doesn't retrieve all the documents from an index

I would like to retrieve all the documents from Elasticsearch, so I referred to the Search Scroll API.
But my question is, it is not returning all the documents, I have 36 documents in one index, for that it was returning 26 only.
Even when I checked with another index, where I have more than 10k documents, there it is also not returning the last 10 documents.
I really don't know why it was returning it like that! Any help will be appreciated! Thanks in advance!
Below the code I've tried:
final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
SearchRequest searchRequest = new SearchRequest("myindex");
searchRequest.scroll(scroll);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query("")//here some query;
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
String scrollId = searchResponse.getScrollId();
SearchHit[] searchHits = searchResponse.getHits().getHits();
while (searchHits != null && searchHits.length > 0) {
SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
scrollRequest.scroll(scroll);
searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
scrollId = searchResponse.getScrollId();
searchHits = searchResponse.getHits().getHits();
for (SearchHits hit: searchHits){
String source=hit.getSourceAsString();
}
}
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
clearScrollRequest.addScrollId(scrollId);
ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
boolean succeeded = clearScrollResponse.isSucceeded();
Today I faced with the same problem while working with an example from:
Elastic Scroll API
First of all, about documents you missed - 10 is default value for the size of requests and based on this we can suppose that one of your requests wasn't handled properly.
In your code first batch of 10 documents isn't handled:
SearchHit[] searchHits = searchResponse.getHits().getHits();
Before while loop you should iterate over your searchHits .
From the first time it was not clear to me in the official documents.
You should change your while loop logic to execute the hit iteration first and the scroll after.
while (searchHits != null && searchHits.length > 0) {
// execute this block first otherwise the scroll will overwrite the initial hits.
for (SearchHits hit: searchHits){
String source=hit.getSourceAsString();
}
SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
scrollRequest.scroll(scroll);
searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
scrollId = searchResponse.getScrollId();
searchHits = searchResponse.getHits().getHits();
}
Another thing to consider is that you can increase the response hit size. from the docs:
The index.max_result_window which defaults to 10,000 is a safeguard, search requests take heap memory and time proportional to from + size.
So the defaulted value for max_result_window is 10k hits, you can also set this value to be something else. this means you can fetch up to 10k hits in 1 search call instead of executing redundant paginations.
You can do this by specifying the size property for searchSourceBuilder before executing the search call like so:
searchSourceBuilder.size(10000);

Initialize an Elasticsearch SearchResponse object before running a query

I am running various Elastic Search queries from my Java code. In order to consolidate my code, I would like to initialize a SearchResponse object before my conditional loops that each run an ElasticSearch query with different settings. This way, I can execute a single line of code once for getting the total hits from the query. You'll get what I mean from the code
#GET
#Path("/search")
public SearchResultsAndFacets search() {
SearchResultsAndFacets srf = new SearchResultsAndFacets();
RestHighLevelClient client = createHighLevelRestClient();
// Build the base query that applies to all searches
SearchSourceBuilder querySourceBuilder = buildQueryWrapper(colNames, sro.q, sro.f,
facetsToUpdate, sro.u, sro.lc);
SearchResponse searchresponse; // This line does not work. How can I initialize this object here (outside of the following conditional loops)?
// Searches executed from the table view to populate a table of documents
if (searchType.equals("table")) {
List<SortParameters> sortParametersList = sortAdapter(sro.s);
searchResponse = runTableQuery(client, querySourceBuilder, sortParameters, offset, limit);
}
// Searches involving geo_point data to populate a leaflet map
if (searchType.equals("contacts")) {
RestHighLevelClient client = createHighLevelRestClient();
ElasticSearchMapService esms = new ElasticSearchMapService();
searchResponse = esms.runContactsMapQuery(querySourceBuilder, client, <some geographic coordinate parameters necessary for this search>);
MapSearchResponse mapSearchResponse = esms.getLocationsFromSearchResponse(searchResponse);
srf.mapSearchResponse = mapSearchResponse;
}
// I would like to include these next few lines here at the end of the conditional loops.
// Currently they must be inside each if clause.
srf.totalHits = searchResponse.getHits().getTotalHits().value;
srf.elapsed = searchResponse.getTook().getMillis();
srf.facetsData = getUpdatedFacetData(facetsToUpdate,
searchResponse, sro.f);
return srf;
}
Elastic's high level REST client for JAVA does not allow initializing a SearchResponse object like this. It is also not possible to do so with
SearchResponse searchResponse = new SearchResponse();
And there is a null pointer error if we do...
SearchResponse searchResponse = new SearchResponse(null);
How can I rewrite this code so that I can fetech totalHits, elapsed and facetsData outside of the conditional loops?

Elasticsearch simultaneously search by two documents

I have two different documents in the Elasticsearch - Decision and Nomination.
Right now I can only search all of the documents wit Decision type.
I use Spring Data Elasticsearch for this purpose:
PageRequest pageRequest = DecisionUtils.createPageRequest(pageNumber, pageSize);
MultiMatchQueryBuilder fuzzyMmQueryBuilder = multiMatchQuery(query, "name", "description").fuzziness("AUTO");
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder().should(fuzzyMmQueryBuilder);
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withIndices(ESDecision.INDEX_NAME).withTypes(ESDecision.TYPE).withPageable(pageRequest);
NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.withQuery(boolQueryBuilder).withPageable(pageRequest).build();
return elasticsearchTemplate.queryForPage(nativeSearchQuery, ESDecision.class);
Is it possible to update this code to search by Decision and Nomination simultaneously in order to get the search result from both of them ? If the answer is yes - please show an example how to implement this and also please show how to determine at search results who is Decision and who is Nomination ? Is there any classification field that can be added into search result entity for this purpose ?

How to use multifieldquery and filters in Lucene.net

I want to perform a multi field search on a lucene.net index but filter the results based on one of the fields. Here's what I'm currently doing:
To index the fields the definitions are:
doc.Add(new Field("id", id.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
doc.Add(new Field("title", title, Field.Store.NO, Field.Index.TOKENIZED));
doc.Add(new Field("summary", summary, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.YES));
doc.Add(new Field("description", description, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.YES));
doc.Add(new Field("distribution", distribution, Field.Store.NO, Field.Index.UN_TOKENIZED));
When I perform the search I do the following:
MultiFieldQueryParser parser = new MultiFieldQueryParser(new string[]{"title", "summary", "description"}, analyzer);
parser.SetDefaultOperator(QueryParser.Operator.AND);
Query query = parser.Parse(text);
BooleanQuery bq = new BooleanQuery();
TermQuery tq = new TermQuery(new Term("distribution", distribution));
bq.Add(tq, BooleanClause.Occur.MUST);
Filter filter = new QueryFilter(bq);
Hits hits = searcher.Search(query, filter);
However, the result is always 0 hits.
What am I doing wrong?
I think I now have a solution. I have discarded the use of the QueryFilter and am using a boolean query to constrain the results before the MultiFieldQuery. So the code will look something like this:
MultiFieldQueryParser parser = new MultiFieldQueryParser(new string[]{"title", "summary", "description"}, analyzer);
parser.SetDefaultOperator(QueryParser.Operator.AND);
Query query = parser.Parse(text);
BooleanQuery bq = new BooleanQuery();
TermQuery tq = new TermQuery(new Term("distribution", distribution));
bq.Add(tq, BooleanClause.Occur.MUST);
bq.Add(query, BooleanClause.Occur.MUST)
Hits hits = searcher.Search(bq);

Resources