QueryResults¶
This class allows you to access and iterate the results of a query to Elasticsearch. It allows you to use Ruby’s Enumerable methods that you already know and love to scroll the results as if they were a standard collector. The class takes care of requesting the results in batches for you and it works seamlessly with or without Elasticsearch’s Scroll API enabled.
You do not need to create instances of this class yourself, instead you’ll get them as return value when you use the #search method of the Index class:
results = index.search(
query: {
term: {
'user.id': 'kimchy'
}
}
)
results.class # => JayAPI::Elasticsearch::QueryResults
#more?¶
This method returns true
if there are more documents in the result set,
false
otherwise. This method is nowadays more or less obsolete. The idea is
that, when this method returns true
then you can call #next_batch to get
the next batch of documents, if it returns false
then you have reached the
end of the result set and subsequent calls to #next_batch won’t yield any
more results.
It is better, however, to use #all instead, since it gives you an Enumerator that you can iterate without worrying about this.
Example:
while results.any?
results.each do |document|
# do something with the document
end
break unless results.more?
results = results.next_batch
end
#each¶
This method allows you to iterate through the current batch of documents. If you call it with a block it will yield each document to the block, if you call it without a block then an Enumerator will be returned, which you then can iterate or transform with any of the methods from Ruby’s standard Enumerable module.
The use of this method is also discouraged, instead you should use #all which will give you the exact same features but you don’t need to fetch the next batch after the reaching the end.
results.each do |document|
# do something with the document
end
results.each.select { |doc| doc.dig('_source', 'type') == 'test_result' }
#all¶
This method allows you to iterate the whole collection of documents matching
your query as if they were a single collection. The QueryResults
class will
take care of fetching more documents for you as you reach the end of the current
batch.
If you call the method with a block each of the documents will be yielded to the block until the end of the whole result set is reached. If you do not provide a block an Enumerator will be returned which you can then iterate, transform or filter with any of the methods from Ruby’s Enumerable module.
Example:
results.all do |document|
# do something with your document
end
results.all.map { |doc| doc['_id'] }
The returned enumerator is lazy, which means that it will only fetch the next batch of documents if you reach the end of the current batch.
#aggregations¶
If the query you passed to the #search method contains any Aggregations they will show up here.
Example:
results = index.search(
aggs: {
'my-agg-name': {
terms: {
field: 'my-field'
}
}
}
)
results.aggregations
{
"my-agg-name": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
# ...
]
}
}
#next_batch¶
Fetches the next batch of documents from Elasticsearch.
Warning
This method returns a new instance of the QueryResults
class, which is the
one containing the data for the next batch, the current instance (the
receiver) of the method call retains the same data.
In this sense you should think of each instance of the QueryResults
class
as immutable.
Example:
if results.more?
results = results.next_batch
# ^
# Not the re-assigning of the variable
end