Skip to content

Reactive meilisearch rest client powered by reactor-netty-http

License

Notifications You must be signed in to change notification settings

honhimW/meilisearch-rest-client

Repository files navigation

Meilisearch Rest Client

License Maven CI Codecov


Meilisearch is a lightning-fast search engine that fits effortlessly into your apps, websites, and workflow.

The goal of this library is to provide a object-oriented, semantic, reactive, and streamlined meilisearch-rest-client, supporting reactivity through reactor-netty-http.

Version

The version number of this library is named by appending .X to the version number in the official documentation.

Doc's Version Library's Version
V1.10(latest) 1.10.X.X
V1.9 1.9.X.X
V1.8 1.8.X.X
V1.7 1.7.X.X
V1.6 1.6.X.X
V1.5 1.5.X.X

Dependencies

By default, this library depends on libraries as fallows:

  • reactor-netty-http(required)
  • jackson(replaceable by providing implementation of io.github.honhimw.ms.JsonHandler)

Installation

# build from sources
$ ./gradlew clean build -x test
# publish to maven local
$ ./gradlew publishToMavenLocal
// Gradle
implementation 'io.github.honhimw:meilisearch-rest-client:1.10.0.0'
<!-- Maven -->
<dependency>
    <groupId>io.github.honhimw</groupId>
    <artifactId>meilisearch-rest-client</artifactId>
    <version>1.10.0.0</version>
</dependency>

Copy Snippets here.


Run Tests

$ ./gradlew test

Create file named profile-test.properties under project root directory.

./meilisearch-rest-client
└── profile-test.properties
meili-search.host=127.0.0.1
meili-search.port=7700
meili-search.api-key=MASTER_KEY

Note: You may also set profiles.active in gradle.properties for loading different properties file such as:

profile-alpha.properties: by setting profiles.active=alpha
profile-beta.properties: by setting profiles.active=beta


Usage

Searching

public static void reactive() {
    JsonHandler jsonHandler = new JacksonJsonHandler();
    @Cleanup
    ReactiveMSearchClient client = ReactiveMSearchClient.create(builder -> builder
        .enableSSL(false)                    // true: https, false: http
        .host("{{meilisearch-server-host}}") // server host
        .port(7700)                          // server port
        .jsonHandler(jsonHandler)
        .httpClient(ReactiveHttpUtils.getInstance(http -> http.readTimeout(Duration.ofMillis(100)))));
    String indexUid = "movies";
    Mono<SearchResponse<Movie>> searchResponse = client.indexes(indexes -> indexes
        .search(indexUid, search -> search
            .find("hello world", Movie.class)));
    List<Movie> hits = searchResponse.block().getHits();
    // or
    List<Movie> hits2 = client.indexes(indexes -> indexes
        .search(indexUid, Movie.class, search -> search
            .find(q -> q
                .q("hello world")
                .limit(1)
            )
            .map(SearchResponse::getHits)
        )
    ).block();
}

public static void blocking() {
    JsonHandler jsonHandler = new JacksonJsonHandler();
    @Cleanup
    MSearchClient client = MSearchClient.create(builder -> builder
        .enableSSL(false)                    // true: https, false: http
        .host("{{meilisearch-server-host}}") // server host
        .port(7700)                          // server port
        .jsonHandler(jsonHandler)
        .httpClient(ReactiveHttpUtils.getInstance(http -> http.readTimeout(Duration.ofMillis(100)))));
    String indexUid = "movies";
    SearchResponse<Movie> searchResponse = client.indexes(indexes -> indexes
        .search(indexUid, search -> search
            .find("hello world", Movie.class)));
    List<Movie> hits = searchResponse.getHits();
    // or
    List<Movie> hits2 = client.indexes(indexes -> indexes
        .search(indexUid, Movie.class, search -> search
            .find(q -> q
                .q("hello world")
                .limit(1)
            )
            .getHits()
        )
    );
}

Search With Details API

public static void reactive() {
    ReactiveTypedDetailsSearch<Movie> searcher = client.indexes().searchWithDetails("movies", Movie.class);
    searcher.find(builder ->builder
            .q("hello world")
            .filter("id < 10")
            .showRankingScore(true)
        )
        .map(response -> {
            Integer estimatedTotalHits = response.getEstimatedTotalHits();
            Long processingTimeMs = response.getProcessingTimeMs();
            return response.getHits();
        })
        .doOnNext(hitDetails -> {
            for(HitDetails<Movie> hitDetail :hitDetails){
                SearchDetails details = hitDetail.getDetails(); // Search Details
                Movie source = hitDetail.getSource();           // Source Document

                Map<String, Object> formatted = details.get_formatted();
                SearchDetails.Geo geo = details.get_geo();
                Double rankingScore = details.get_rankingScore();
            }
        })
        .subscribe()
}

public static void blocking() {
    TypedDetailsSearch<Movie> searcher = client.indexes().searchWithDetails("movies", Movie.class);
    SearchDetailsResponse<Movie> response = searcher.find(builder -> builder
        .q("hello world")
        .filter("id < 10")
        .showRankingScore(true)
    );
    Integer estimatedTotalHits = response.getEstimatedTotalHits();
    Long processingTimeMs = response.getProcessingTimeMs();
    List<HitDetails<Movie>> hitDetails = response.getHits();
    for(HitDetails<Movie> hitDetail :hitDetails){
        SearchDetails details = hitDetail.getDetails(); // Search Details
        Movie source = hitDetail.getSource();           // Source Document

        Map<String, Object> formatted = details.get_formatted();
        SearchDetails.Geo geo = details.get_geo();
        Double rankingScore = details.get_rankingScore();
    }
}

Await On TaskInfo, Only in blocking

public static void blocking() {
    TaskInfo saveTask = client.indexes(indexes -> indexes
        .documents("movies").save(jsonQuote("{'id':100}")));
    TaskView taskView = saveTask.await();
    TaskStatus status = taskView.getStatus();
    assert status == TaskStatus.SUCCEEDED || status == TaskStatus.FAILED;
}