elasticsearch sort by _doc for scroll not returning any results - elasticsearch

I am trying to run a scroll query and get the results by sorting on "_doc" field. But the scroll is always returning empty resultest. Below the scroll i am trying. I am using elasticsearch version 2.3.4
SearchResponse scrollResp = client.prepareSearch(indexName).setTypes(indexType)
.setScroll(TimeValue.timeValueMillis(scrollTimeout))
.addSort("_doc" , SortOrder.ASC)
.setSearchType(SearchType.QUERY_THEN_FETCH)
.setQuery(query)
.setFrom(pageIndex)
.setSize(scrollSize)
//.setFetchSource(true)
.execute()
.actionGet();
return scrollResp;
But if i replace the same query with sort on "id" field it works fine. Am i doing anything wrong here?
SearchResponse scrollResp = client.prepareSearch(indexName).setTypes(indexType)
.setScroll(TimeValue.timeValueMillis(scrollTimeout))
.addSort(new FieldSortBuilder("id"))
.setSearchType(SearchType.QUERY_THEN_FETCH)
.setQuery(query)
.setFrom(pageIndex)
.setSize(scrollSize)
//.setFetchSource(true)
.execute()
.actionGet();
return scrollResp;

Related

Elasticsearch Query: Boosting specific field

I am using Elasticsearch 2.4.3 and want to boost specific fields in my query. Is this possible? I only see how I can boost an index.
Greetings!
UPDATE
Mapping:
"firstName":{"type":"string",
"analyzer":"customNGram"
},
"lastName":{
"type":"string",
"analyzer":"customNGram"
},
"note":{
"type":"string",
"analyzer":"customNGram"
}
Query (Java API):
QueryBuilder qb = new BoolQueryBuilder()
.must(QueryBuilders.matchQuery("_all", term)
.analyzer("atsCustomSearchAnalyzer")
.operator(Operator.AND));
SearchRequestBuilder searchRequestBuilder = elasticsearchClient.prepareSearch("persons", "activities").setTypes("person", "activity")
.setQuery(qb)
.addHighlightedField("*").setHighlighterRequireFieldMatch(false)
.setHighlighterOrder("score")
.setHighlighterFragmentSize(150)
.setHighlighterForceSource(true)
.setSize(100)
.addIndexBoost("persons", 200)
.setFrom(offset);
return searchRequestBuilder.execute().get();
If you split up your match-query to match individual fields, eg using a multi match query (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html), you can boost the field you like. So something like:
QueryBuilder qb = new BoolQueryBuilder()
.must(QueryBuilders.multiMatchQuery(term, "firstName^3",
"lastName^3", "note")
.analyzer("atsCustomSearchAnalyzer")
.operator(Operator.AND));
should boost firstName and lastName 3 times relative to the note field.

Post Filter Query in Elasticsearch 2.3.3 using Java

I have built a web app on top of elasticsearch (v2.3.3). To filter the query, I am using post filter of elasticsearch. But I came to know that, if I use post filter then the performance benefit of filtering will be lost since I am not using any aggregation or differential filtering. (Reference: https://www.elastic.co/guide/en/elasticsearch/guide/current/_post_filter.html)
This is how my elasticsearch client looks like:
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),
9300));
SearchResponse response = client.prepareSearch("index_name")
.setTypes("index_type")
.setQuery(QueryBuilders.simpleQueryStringQuery(query)
.field("newContent").field("T"))
.setPostFilter(QueryBuilders.termQuery(Collection, true))
.setFetchSource(new String[] { "U", "UE", "UD", "T" }, null)
.setVersion(true).addHighlightedField("newContent").setFrom(0)
.setSize(10).execute().actionGet();
I have also read that filtered query is depreciated in elasticsearch 2.x versions. Is there any other way which will help me to apply a filter before the query is executed? I might be missing something obvious. I would appreciate your help.
You simply need to bring the filter present in post filter inside a bool/filter query. Try to do hits instead:
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.simpleQueryStringQuery(query)
.field("newContent").field("T"))
.filter(QueryBuilders.termQuery(Collection, true));
SearchResponse response = client.prepareSearch("index_name")
.setTypes("index_type")
.setQuery(boolQuery)
.setFetchSource(new String[] { "U", "UE", "UD", "T" }, null)
.setVersion(true).addHighlightedField("newContent").setFrom(0)
.setSize(10).execute().actionGet();

How to sort by _doc using elasticsearch java client

I want to iterate on entire elasticsearch index/type. I am using scroll in java client as below
SearchResponse scrollResp = client.prepareSearch(test)
.setSearchType(SearchType.SCAN)
.setScroll(new TimeValue(60000))
.setQuery(qb)
.setSize(100).execute().actionGet();
As suggested in docs in the link.
"Scroll requests have optimizations that make them faster when the sort order is _doc. If you want to iterate over all documents regardless of the order, this is the most efficient option"
"sort": [
"_doc"
]
How to set sort order to "_doc" in java client code above?
Use this :
SearchResponse scrollResp = elasticsearchTemplate.client.prepareSearch(test)
.setSearchType(SearchType.SCAN)
.setScroll(new TimeValue(60000))
.setQuery(qb).addSort("_doc" , SortOrder.ASC)
.setSize(100).execute().actionGet();

Retrieve a document from elastic search by matching two fields

My data are stored in elastic search as shown below
{
"identifier":{
"source":"source 1",
"id":"22081070"
},
"title":"Book 1",
"published":2011,
"types":[
"type1",
"type2,
"type3"
]
}
Is there a way to retrieve a document with specific "identifier.id" and "identifier.source" parameters? For example I am retrieving the above document with its id as an input with the following:
QueryBuilder queryBuilder = QueryBuilders.matchQuery("identifier.id", "22081070");
SearchResponse searchResponse = client.prepareSearch("test-index")
.setTypes("type").setQuery(queryBuilder).execute().actionGet();
but I know know how to add the "identifier.source" as a match parameter.
Try this:
BoolQueryBuilder boolQuery = new BoolQueryBuilder();
QueryBuilder queryBuilder1 = QueryBuilders.matchQuery("identifier.id", "22081070");
QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("identifier.source", "source 1");
boolQuery.must(queryBuilder1).must(queryBuilder2);
SearchResponse searchResponse = client.prepareSearch("test-index")
.setTypes("type").setQuery(boolQuery).execute().actionGet();

How to rewrite ElasticSearch DSL query with the Java API

I have got a working query for ElasticSearch, but I have problems to execute the same query with the Java API of ElasticSearch.
How can I express the query below with the Java API of ElasticSearch?
---
size: 0
query:
match_all: []
facets:
age:
statistical:
field : timestamp
It should be something like:
client.prepareSearch("yourindex")
.setTypes("yourtype")
.setQuery(QueryBuilders.matchAllQuery())
.addFacet(FacetBuilders.statisticalFacet("age").field("timestamp"))
.setSize(0)
.execute()
.actionGet();
You can convert your query DSL to a JSON string, and then wrap it with QueryBuilders.wrapperQuery() or WrapperQueryBuilder(), finally do the query with Java API like this.
SearchResponse response = client.prepareSearch("yourIndex")
.setTypes("yourType")
.setQuery(dslQB)
.setFrom(currentItem)
.setSize(pageSize)
.execute()
.actionGet();
`

Resources