Searching from the SDK

The Java SDK provides an API that supports Full Text Search.

Using Full Text Search from the Java SDK

By means of the Java SDK, Full Text Search queries can be performed on Full Text Indexes; and result-sets sorted.

A general introduction to Full Text Search, with pointers to detailed descriptions of its principal features, is provided in Full Text Search: Fundamentals.

The current page features a code example that demonstrates the Java SDK Full Text Search API. The example assumes that Couchbase Server is running, and that the username Administrator and the password password provide authorization for performing the searches. It also assumes that the travel-sample bucket has been installed. For information on creating users and managing roles, see Authorization. For information on installing sample buckets, see 6.0@server:settings:settings.adoc.

The example also assumes the existence of three specific Full Text Indexes, defined on the travel-sample bucket. These are:

  • travel-sample-index-unstored: Uses only the default settings.

  • travel-sample-index-stored: Uses default settings, with one exception: dynamic fields are stored, for the whole index.

  • travel-sample-index-hotel-description: Indexes only the description fields of hotel documents, and disables the default type mapping. The index has a custom analyzer named myUnicodeAnalyzer defined on it: the analyzer’s main characteristic is that it uses the unicode tokenizer.

See Creating Indexes for details on how to create these indexes: they can be created interactively, by means of the Couchbase Web Console; however, there may be greater efficiency in using the Couchbase REST API, as described in the section Index Creation with the REST API. The JSON objects that constitute index-definitions (for inclusion as bodies to the index-creation REST calls), are provided in Demonstration Indexes.

The example features the following Full Text Searches on the travel-sample bucket, within Couchbase Server:

  • Simple Text Query on a single word, targeting an index with dynamic fields unstored.

  • Simple Text Query on Non-Default Index, specifying an index that consists only of content derived from a specific field from a specific document-type.

  • Simple Text Query on Stored Field, specifying the field to be searched; targeting an index with dynamic fields stored, to ensure that field-content is included in the return object.

  • Match Query with Facet, showing how query-results can be displayed either by row or by hits; and demonstrating use of a facet, which provides aggregation-data.

  • DocId Query, showing results of a query on two document IDs.

  • Unanalyzed Term Query with Fuzziness Level of 0, demonstrating how to query on a term with no analysis. Zero fuzziness is specified, to ensure that matches are exact.

  • Unanalyzed Term Query with Fuzziness Level of 2, which is almost identical to the immediately preceding query; but which this time specifies a fuzziness factor of 2, allowing partial matches to be made. The output from this query can be compared to that of the one immediately preceding.

  • Match Phrase Query, using Analysis, for searching on a phrase.

  • Phrase Query, without Analysis, for searching on a phrase without analysis supported.

  • Query String Query, showing how a query string is specified as search-input.

  • Conjunction Query, whereby two separate queries are defined and then run as part of the search, with only the matches returned by both included in the result-object.

  • Wild Card Query, whereby a wildcard is used in the string submitted for the search.

  • Numeric Range Query, whereby minimum and maximum numbers are specified, and matches within the range returned.

  • Regexp Query, whereby a regular expression is submitted, to generate the conditions for successful matches.

Detailed Example

The following example demonstrates Full Text Search queries that can be made with the Java SDK.

package com.couchbase.example.fts;

import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.search.SearchQuery;
import com.couchbase.client.java.search.facet.SearchFacet;
import com.couchbase.client.java.search.queries.*;
import com.couchbase.client.java.search.result.SearchQueryResult;
import com.couchbase.client.java.search.result.SearchQueryRow;

public class JavaFtsExamples {

    public static void simpleTextQuery(Bucket bucket) {
        String indexName = "travel-sample-index-unstored";
        MatchQuery query = SearchQuery.match("swanky");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10));

        printResult("Simple Text Query", result);
    }

    public static void simpleTextQueryOnStoredField(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        MatchQuery query = SearchQuery.match("MDG").field("destinationairport");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10).highlight());

        printResult("Simple Text Query on Stored Field", result);
    }

    public static void simpleTextQueryOnNonDefaultIndex(Bucket bucket) {
        String indexName = "travel-sample-index-hotel-description";
        MatchQuery query = SearchQuery.match("swanky");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10));

            printResult("Simple Text Query on Non-Default Index", result);
    }

    public static void textQueryOnStoredFieldWithFacet(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        MatchQuery query = SearchQuery.match("La Rue Saint Denis!!")
            .field("reviews.content");

        SearchQueryResult result = bucket.query(
        new SearchQuery(indexName, query).limit(10).highlight()
            .addFacet("Countries Referenced", SearchFacet.term("country", 5)));

        printResult("Match Query with Facet, Result by Row", result);

        System.out.println();
        System.out.println("Match Query with Facet, Result by hits:");
        System.out.println(result.hits());

        System.out.println();
        System.out.println("Match Query with Facet, Result by facet: ");
        System.out.println(result.facets());
    }

    public static void docIdQueryMethod(Bucket bucket) {
        String indexName = "travel-sample-index-unstored";
        DocIdQuery query = SearchQuery.docId("hotel_26223", "hotel_28960");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query));

        printResult("DocId Query", result);
    }

    public static void unAnalyzedTermQuery(Bucket bucket, int fuzzinessLevel) {
        String indexName = "travel-sample-index-stored";
        TermQuery query = SearchQuery.term("sushi").field("reviews.content")
            .fuzziness(fuzzinessLevel);

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(50).highlight());

        printResult("Unanalyzed Term Query with Fuzziness Level of "
            + fuzzinessLevel + ":", result);
    }

    public static void matchPhraseQueryOnStoredField(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        MatchPhraseQuery query = SearchQuery.matchPhrase("Eiffel Tower")
            .field("description");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10).highlight());

        printResult("Match Phrase Query, using Analysis", result);
    }

    public static void unAnalyzedPhraseQuery(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        PhraseQuery query = SearchQuery.phrase("dorm", "rooms")
            .field("description");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10).highlight());

        printResult("Phrase Query, without Analysis", result);
    }

    public static void conjunctionQueryMethod(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        MatchQuery firstQuery = SearchQuery.match("La Rue Saint Denis!!")
            .field("reviews.content");
        MatchQuery secondQuery = SearchQuery.match("boutique")
            .field("description");

        ConjunctionQuery conjunctionQuery =
            SearchQuery.conjuncts(firstQuery, secondQuery);

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, conjunctionQuery).limit(10).highlight());

        printResult("Conjunction Query", result);
    }

    public static void queryStringMethod(Bucket bucket) {
        String indexName = "travel-sample-index-unstored";
        QueryStringQuery query = SearchQuery.queryString("description: Imperial");

        SearchQueryResult result = bucket.query(
        new SearchQuery(indexName, query).limit(10));

        printResult("Query String Query", result);
    }

    public static void wildCardQueryMethod(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        WildcardQuery query = SearchQuery.wildcard("bouti*ue").field("description");

        SearchQueryResult result = bucket.query(
        new SearchQuery(indexName, query).limit(10).highlight());

        printResult("Wild Card Query", result);
    }

    public static void numericRangeQueryMethod(Bucket bucket) {
        String indexName = "travel-sample-index-unstored";
        NumericRangeQuery query = SearchQuery.numericRange().min(10100).max(10200)
            .field("id");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10));

        printResult("Numeric Range Query", result);
    }

    public static void regexpQueryMethod(Bucket bucket) {
        String indexName = "travel-sample-index-stored";
        RegexpQuery query = SearchQuery.regexp("[a-z]").field("description");

        SearchQueryResult result = bucket.query(
            new SearchQuery(indexName, query).limit(10).highlight());

        printResult("Regexp Query", result);
    }

    private static void printResult(String label, SearchQueryResult resultObject) {
        System.out.println();
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = =");
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = =");
        System.out.println();
        System.out.println(label);
        System.out.println();

        for (SearchQueryRow row : resultObject) {
            System.out.println(row);
        }
    }

    public static void main(String[] args) {
        // Access the cluster that is running on the local host, authenticating with
        // the username and password of any user who has the "FTS Searcher" role
        // for the "travel-sample" bucket...
        //
        Cluster cluster = CouchbaseCluster.create("localhost");
        cluster.authenticate("Administrator", "password");
        Bucket travelSample = cluster.openBucket("travel-sample");

        simpleTextQuery(travelSample);

        simpleTextQueryOnStoredField(travelSample);

        simpleTextQueryOnNonDefaultIndex(travelSample);

        textQueryOnStoredFieldWithFacet(travelSample);

        docIdQueryMethod(travelSample);

        unAnalyzedTermQuery(travelSample, 0);

        unAnalyzedTermQuery(travelSample, 2);

        matchPhraseQueryOnStoredField(travelSample);

        unAnalyzedPhraseQuery(travelSample);

        conjunctionQueryMethod(travelSample);

        queryStringMethod(travelSample);

        wildCardQueryMethod(travelSample);

        numericRangeQueryMethod(travelSample);

        regexpQueryMethod(travelSample);

        cluster.disconnect();
    }
}