Skip to main content

Search Documents

Tigris offers a realtime search for documents in a collection. Searching is by default enabled for a collection, there is no setup. This guide section will walk through how to use Tigris search in different scenarios.

Request Specification

HTTP APIHTTP MethodURL ParamsResource
SEARCHPOST
  • Database Name
  • Collection Name
  • /databases/{db}/collections/{collection}/documents/search

    Request Payload

    {
    "q": string,
    "search_fields": [string],
    "facet": {
    <field1>: {
    "size": number
    },
    },
    "filter": {
    <field1>: number|string|boolean,
    <field2>: {<$lt|$lte|$gt|$gte>: number},
    <$and|$or>: [<field3>: number|string|boolean, expr1, expr2...]
    },
    "include_fields": [string],
    "exclude_fields": [string],
    "page_size": number,
    "page": number
    }

    Understanding the request payload:

    • The q is a query string for searching across text fields.
    • The search_fields an array of fields to project search query against. By default, query will be searched against all text fields.
    • The facet query to aggregate results on given fields.
    • The filter syntax are documented here.
    • The include_fields an optional param to only include the fields specified in the array.
    • The exclude_fields an optional param to exclude the fields.
    • The page_size an optional key that can set to control the number of hits to be returned per page, default is 20.
    • The page an optional key that can set to specify the page to retrieve. If page is set then only hits for this page is returned.

    Example collection

    Let's first have the collection.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/createOrUpdate' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "schema":{
    "title":"catalog",
    "properties":{
    "id":{
    "type":"integer",
    "format":"int32",
    "autoGenerate":true
    },
    "name":{
    "type":"string"
    },
    "price":{
    "type":"number"
    },
    "brand":{
    "type":"string"
    },
    "labels":{
    "type":"string"
    },
    "popularity":{
    "type":"integer"
    },
    "reviews":{
    "type":"object",
    "properties":{
    "author":{
    "type":"string"
    },
    "rating":{
    "type":"number"
    }
    }
    }
    },
    "primary_key":[
    "id"
    ]
    }
    }'

    Assuming an e-commerce website that has the above collection catalog and has 6 products(documents) in it.

    idnamepricebrandlabelspopularityreviews
    1fiona handbag99.9michael korspurses8{"author": "alice", "rating": 7}
    2tote bag49coachhandbags9{"author": "olivia", "rating": 8.3}
    3sling bag75coachpurses9{"author": "alice", "rating": 9.2}
    4sneakers shoes40adidasshoes10{"author": "olivia", "rating": 9}
    5running shoes89nikeshoes10{"author": "olivia", "rating": 8.5}
    6running shorts35adidasclothing7{"author": "olivia", "rating": 7.5}

    Searching for documents

    Search consists of executing a query against one or more text fields. Let's perform a simple search query to lookup any items matching "running".

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running"
    }'
    info

    Search is case insensitive i.e. a search for term "ruNninG" would match all of ["Running", "running", "RUnnIng", "RUNNING"] etc.

    By default, search is performed over individual terms in the text. For example, search for a query string adventure park in a dataset would yield following results:

    1. "California's kids adventure park and Safari"
    2. "Adventure island and water park"
    3. "Long Island water park and adventure activities"
    4. "Six flags kids recreation and adventure park"
    5. "Hollywood adventure park and studios"
    6. "Seaworld adventure and theme park"

    The search phrase can be escaped in query for exact match. In the above example, querying for exact phrase \"adventure park\" would return:

    1. "California's kids adventure park and Safari"
    2. "Six flags kids recreation and adventure park"
    3. "The Great America adventure park and Zoo"

    Phrases can still be combined with keywords for richer text search. Continuing above example, the query string kids \"adventure park\" would result in:

    1. "California's kids adventure park and Safari"
    2. "Six flags kids recreation and adventure park"
    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "\"adventure park\""
    }'

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "kids \"adventure park\""
    }'

    Match all search query

    When query string isn't specified or an empty string (""), a match all query is performed. It returns all searchable documents, modified by any filters or search parameters used.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{}'
    tip

    Returning all documents is typically useful when used in conjunction with filter, or when performing a faceted search across the collection.

    Project search query against specific fields

    We can optionally project the search query against selected fields. Continuing previous example of searching for "running", we may not want to search in reviews field and avoid any unwanted results.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "search_fields": ["name", "labels"]
    }'

    Refine the search results using filters

    Let's adjust the query to only return items in price range of [40, 90). We can use filters in search to further refine the results.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "search_fields": [ "name", "labels" ],
    "filter": {
    "$and": [
    {
    "price": { "$gte": 40 }
    },
    {
    "price": { "$lt": 90 }
    }
    ]
    }
    }'

    Exact text match

    Filters can be used to match against one or more field values in a collection. For example, to fetch all items from brand "adidas".

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "filter": {
    "brand": "adidas"
    }
    }'

    We can additionally retrieve the number of items a particular brand has and unique labels, that match our search query.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "search_fields": [
    "name",
    "labels"
    ],
    "filter": {
    "$and": [
    {
    "price": { "$gte": 40 }
    },
    {
    "price": { "$lt": 90 }
    }
    ]
    },
    "facet": {
    "brand": { "size": 10 },
    "labels": { "size": 10 }
    }
    }'

    Facets are a specific use-case of filters, and can only be used for filterable attributes.

    Faceted content navigation UI

    Common application for faceted search is to build UX with quick filters, that users can use to narrow search results in real-time. Faceted search interface presents intuitive content navigation to the end user.

    Sorting the search results

    Tigris lets you specify an order to sort the search results. We can specify a ranking order in our search query to have results sorted with more popular items appearing first.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "search_fields": ["name", "labels"],
    "sort": [
    {"popularity": "$desc"}
    ]
    }'

    Many documents may have the same popularity score, we can specify additional user-defined sortable field to break the tie.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "search_fields": ["name", "labels"],
    "sort": [
    {"popularity": "$desc"},
    {"reviews.rating": "$desc"}
    ]
    }'

    The results will be first sorted by value of popularity field, reviews.rating will be used to decide ordering if two matching documents have same popularity.

    note

    Documents can only be sorted by integer, number and date-time type of collection fields.

    Specifying document fields to retrieve

    Search query can be programmed to return only specific fields in a document in search results. We may only need to retrieve product name, brand and price for our interface.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "include_fields": ["name", "price", "brand"]
    }'

    On the contrary, exclusion of fields is useful to exclude/hide potentially sensitive fields or internal metadata from the document. To include all fields except id and reviews from documents in search results.

    curl -L 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "exclude_fields": ["id", "reviews"]
    }'
    note

    Field selection does not impact searching, filtering and faceting capabilities for that field. For example, if reviews field is not included in documents in search results, it could still be used for text querying, filtering and/or faceting; just that matched documents won't include reviews field.

    Case Insensitive Search Result Filtering

    Search is case-insensitive but the filtering to restrict the search result is case-sensitive by default. Tigris supports Collation which allows you to specify string comparison rules for filtering on text fields. Set the case to ci in the collation object to make it case-insensitive. The following example is showing when you are searching for text "running" and you need to filter by brand field, but you don't care about the case.

    curl 'http://localhost:8081/v1/databases/catalogdb/collections/catalog/documents/search' \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
    "q": "running",
    "filter": {
    "brand": "Adidas"
    },
    "collation": {
    "case": "ci"
    }
    }'