elastic_app_search 0.3.0 icon indicating copy to clipboard operation
elastic_app_search: ^0.3.0 copied to clipboard

Dart/Flutter package for using Elastic App Search through a simple API returning easy to handle objects

@hikeland https://dart.dev/ https://flutter.dev/

Dart/Flutter package for using Elastic App Search through a simple API returning easy to handle objects #

Elastic

This package is a ready-to-use API for Elastic App Search.

⚠️ You need an active deployment on Elastic to use this service.

This package does not intend to learn you how Elastic App Search is working, it is just intended to help you make queries and manipulate results easily, assuming that you already know Elastic App Search principles.

Here is a simple example of how you can query your Elastic engine:

final service = ElasticAppSearch(
  endPoint: "https://host-2376rb.api.swiftype.com",
  searchKey: "search-371auk61r2bwqtdzocdgutmg",
);

ElasticResponse response = await service
  .engine("search-ui-examples")
  .query("mountains")
  .filter("states", isEqualTo: "California")
  .filter("world_heritage_site", isEqualTo: true)
  .resultField("title")
  .resultField("description", snippetSize: 140)
  .page(1, size: 50)
  .get();

for (ElasticResult result in response.results) {
  final data = result.data;
  if (data != null) {
    print("${data["title"]}: ${data["description"]}");
  }
}

This example will query the parks containing parks in any field of the documents. The results will be filtering the parks based in California, with the flag world_heritage_site set to true. Only the title and a snippet of 140 chars of the description of the park will be returned by the query. We request the first page, limited to 50 documents.

A full use case is available in example/main.dart, with the following rendering: #

  • The search bar makes dynamic queries to Elastic
  • The popup menu allows you to filter parks if they are World Heritage or not

App preview

Table of contents #

ElasticAppSearch #

Before any operation, you need to create an instance of ElasticAppSearch.

ParamTypeDescription
endPointStringThe URL of your end point
searchKeyStringThe search key of your deployment

Both values are available in your deployment, when going to App Search then Credentials. Warning: use the search-key, not the private-key!

final service = ElasticAppSearch(
    endPoint: "https://localhost:5601", 
    searchKey: "search-soaewu2ye6uc45dr8mcd54v8",
);

ElasticEngine #

All the queries must be sent to an engine. To make instantiating an engine easy, we created this syntax:

TypeDescription
StringThe name of your engine
final engine = service.engine("engine_name");

ElasticQuery #

The only required parameter to instanciate a query is a string which is the word you are looking for through your documents.

🔍 See https://www.elastic.co/guide/en/app-search/current/search.html

TypeDescription
StringThe keyword
final query = engine.query("query");

Precision #

This setting is available through the query modifier .precision

The value of the precision parameter must be an integer between 1 and 11, inclusive. The range of values represents a sliding scale that manages the inherent tradeoff between precision and recall. Lower values favor recall, while higher values favor precision.

🔍 See https://www.elastic.co/guide/en/app-search/current/search-api-precision.html

final query = query.precision(5);

Search filters #

This setting is available through the query modifier .filter

This feature intends to filter documents that contain a specific field value. It's only available on text, number, and date fields.

There are three types of filters:

  • all: All of the filters must match. This functions as an AND condition. To add a filter to "all" filters, use isEqualTo or whereIn.
  • any: At least one of the filters must match. This functions as an OR condition. To add a filter to "any" filters, use isEqualToAny or whereInAny.
  • none: All of the filters must not match. This functions as a NOT condition. To add a filter to "none" filters, use isEqualNotTo or whereNotIn.

🔍 See https://www.elastic.co/guide/en/app-search/current/filters.html

ParamTypeDescription
(unnamed)StringThe field name
isEqualTodynamicThe value that the field must match
isEqualNotTodynamicA value to exclude from the results
isEqualToAnydynamicSimilar to isEqualTo, but handled as a "OR" condition
whereInList<dynamic>The field must match one of these values
whereNotInList<dynamic>An array of values to exclude from the results
whereInAnyList<dynamic>Similar to whereIn, but handled as a "OR" condition
isGreaterThanOrEqualToDateTime or doubleInclusive lower bound of the range
isLessThanDateTime or doubleExclusive upper bound of the range

Warning: You cannot use isEqualTo and whereIn on the same field at the same time, otherwise it will raise an exception.

final query = query.filter("field", isEqualTo: "value");
final query = query.filter("field", isEqualTo: true);
final query = query.filter("field", whereIn: ["value1", "value2"]);
final query = query.filter("field", isGreaterThanOrEqualTo: 50, isLessThan: 100);

Search fields #

This setting is available through the query modifier .searchField

It will restrict a query to search only specific fields. Restricting fields will result in faster queries, especially for schemas with many text fields Only available within text fields.

Weight is given between 10 (most relevant) to 1 (least relevant).

🔍 See https://www.elastic.co/guide/en/app-search/current/search-fields-weights.html

ParamTypeDescription
(unnamed)StringThe field name
weightint (optionnal)The weight of the field in the query
final query = query
  .searchField("field1", weight: 8)
  .searchField("field2", weight: 3);

Result fields #

This setting is available through the query modifier .resultField

The fields which appear in search results and how their values are rendered.

Raw is an exact representation of the value within a field. Snippet is a representation of the value within a field, where query matches are returned in a specific field and other parts are splitted, in order to user [RichText] to display the results and highlight the query matches.

🔍 See https://www.elastic.co/guide/en/app-search/current/result-fields-highlights.html

ParamTypeDescription
(unnamed)StringThe field name
rawSizeint (optionnal)The length of the field value which is returned
snippetSizeint (optionnal)The length of the snippet value which is returned
fallbackbool (optionnal)If true, return the raw text field if no snippet is found. If false, only use snippets.
final query = query
  .resultField("field1", rawSize: 80)
  .resultField("field2", snippetSize: 80)
  .resultField("field3", rawSize: 80, snippetSize: 80, fallback: true);

Facets #

This setting is available through the query modifier .facet

Provides the counts of each value (or each range of value if you provide a range) for a field.

🔍 See https://www.elastic.co/guide/en/app-search/current/facets.html

ParamTypeDescription
(unnamed)StringThe field name
nameString (optionnal)Name given to facet.
isMoreThanOrEqualToDateTime or double (optionnal)Inclusive lower bound of the range.
isLessThanDateTime or double (optionnal)Exclusive upper bound of the range.
final query = query
  .facet("dateField",
    isMoreThanOrEqualTo: DateTime.utc(1984),
    isLessThan: DateTime.utc(2014),
  );

ElasticResponse #

The response object contains two parts, the meta in a ElasticResponseMeta object and the results in a list of ElasticResult objects.

🔍 See https://www.elastic.co/guide/en/app-search/current/search.html#search-api-response-body

ParamTypeDescription
metaElasticResponseMetaObject delimiting the results meta data
resultsList<ElasticResult>Array of results matching the search

ElasticResponseMeta #

An object containing information about the results, especially the pagination details in page.

ParamTypeDescription
requestIdStringID representing the request. Guaranteed to be unique
warningsList<dynamic>Array of warnings for the query
alertsList<dynamic>Array of alerts for your deployment
pageElasticMetaPageObject delimiting the pagination meta data

ElasticResponseMetaPage

Object delimiting the results meta data.

ParamTypeDescription
currentintNumber representing the current page of results
sizeintNumber representing the results per page
totalPagesintNumber representing the total pages of results
totalResultsintNumber representing the total results across all pages

ElasticResult #

An object presenting a result to the query.

The data param is a map of the fields requested with the .searchResult modfifier. If this modifier was omitted, all the fields of the document are returned.

The snippets is a map of the snippets returned by the query, if requested with the .searchResult modfifier. By default, Elastic returns the snippets as HTML snippets. This package manipulates the result to return some stuff that can be handled by Flutter: an ElasticResultSnippet object.

ParamTypeDescription
dataMap<String, dynamic>A map of the raw data of the document
snippetsMap<String, ElasticResultSnippet>A map of the snippets
metaElasticResultMetaAn object containing information about a given result

ElasticResultMeta

An object containing information about a given result.

ParamTypeDescription
scoredoubleThe relevance of the result

ElasticResultSnippet

An object contaning the snippet of the result. If you don't want to display your search results with highlights on the matching keyword, just ignore textParts and highlights and use only fullText.

textParts and highlights can be used to build a RichText widget in Flutter, please look at the example of the package to have a concrete example.

ParamTypeDescription
fullTextStringThe full snippet
textPartsList<String>The snippet splitted in parts around the matched query
highlightsList<String>The words matching the query

Third party packages #

This app uses some external librairies:

  • [x] freezed to generate immutable models
  • [x] dio for http requests
  • [x] html_unescape to strip html tags from results

Credits #

This package was originally created for my personnal needs but feel free to use it, it does not covers all the features available in Elastic App Search, but I will try to cover all the features over time.

I am not related to Elastic in any way, I am just a developer who needed to use this API and created this library to do so.

If you have questions, feel free to ask on Twitter.

LICENSE: MIT #

6
likes
110
pub points
66%
popularity

Publisher

verified publisher iconjulienlebren.dev

Dart/Flutter package for using Elastic App Search through a simple API returning easy to handle objects

Repository (GitHub)
View/report issues

Documentation

API reference

License

Icon for licenses.MIT (LICENSE)

Dependencies

dio, flutter, freezed_annotation, html_unescape

More

Packages that depend on elastic_app_search