search mobile facets autocomplete spellcheck crawler rankings weights synonyms analytics engage api customize documentation install setup technology content domains user history info home business cart chart contact email activate analyticsalt analytics autocomplete cart contact content crawling custom documentation domains email engage faceted history info install mobile person querybuilder search setup spellcheck synonyms weights engage_search_term engage_related_content engage_next_results engage_personalized_results engage_recent_results success add arrow-down arrow-left arrow-right arrow-up caret-down caret-left caret-right caret-up check close content conversions-small conversions details edit grid help small-info error live magento minus move photo pin plus preview refresh search settings small-home stat subtract text trash unpin wordpress x alert case_deflection advanced-permissions keyword-detection predictive-ai sso

Search

Searching is how you read data and generate results from the documents stored within your Engines. The Search endpoint will be invoked each time a search is performed by a user. Unlike the other endpoints, which allow you to customize Engines, view analytics, tune relevance, or index documents, Search is for, well... Searching!

You can use your Public Search Key or your Private API Key to query the Search endpoint. The Public Search Key is for performing search using client side JavaScript, within mobile application development, or any other context where you are at risk of exposing your API Key.

The Public Search Key key begins with: search-. The responses generated by the search endpoint should contain data from your engines that you want your users to see. That is why it has its own special, public key.

The Search API Reference is available here.

What do I search?

Search is all about finding documents. A document is an individual JSON object. When you add data into your Engines, you are taking database or backend API objects and indexing them. But what does it mean, to index? To better understand this, we will look no further than a JSON object:

{
  "name": "SuperObject",
  "authors": "Examplio McDemonstratio",
  "downloads": "98765",
  "info": "A stunning look at potential."
}  

That is one object. Your datastore will likely contain many.

During indexing, your set of objects, of documents, is evaluated to develop a schema. The keys are translated into Fields. The values are, by default, given the type of text. Prior to your data being indexed, the schema is created:

Existing Field Type
name Text
authors Text
downloads Text
info Text

Each document that you index can now be considered part of a set of data. This changes the objects in a small way:

{
  "id": "1234",
  "name": "SuperObject",
  "authors": "Examplio McDemonstrate",
  "downloads": "98765",
  "info": "A stunning look at potential."
}  

Each one now contains an id, this id is how your documents are known to your Engines. By belonging to a defined - though still flexible - schema, the Engine can get deep into its analysis of the documents. The end result is the ability to search vast sets of objects, of documents, with great precision.

How do I search?

If you are the visitor, then you arrive at an application, seek out the search bar or search box, or magic box, enter some text, then hit enter. If search is fast and relevant, then they click on a result, their experience continues and they consume the content, purchase the project, or accomplish whatever it was they sent out to do.

If you are the developer, then you develop applications that access a robust set of APIs. You can access the APIs via an official client, like Python, Ruby, JavaScript, NodeJS, or Java. Or, you can weave in whatever sort of programmatic brilliance that you can dream up.

The visitor has it easy. They are not aware of the deep logic that is happening below the interface with which they interact. The act of searching, in its most simple form, is a request against an Engine wherein the document they seek is indexed.

Example - Performing a simple search.
curl -X POST 'https://host-2376rb.api.swiftype.com/api/as/v1/engines/ruby-gems/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer search-qcqrj73hmom796c98r22zeao' \
-d '{
  "query": "search"
}'

Example - Performing a simple search.
No Java example available, showing cURL
curl -X POST 'https://host-2376rb.api.swiftype.com/api/as/v1/engines/ruby-gems/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer search-qcqrj73hmom796c98r22zeao' \
-d '{
  "query": "search"
}'

Example - Performing a simple search.
No Node example available, showing cURL
curl -X POST 'https://host-2376rb.api.swiftype.com/api/as/v1/engines/ruby-gems/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer search-qcqrj73hmom796c98r22zeao' \
-d '{
  "query": "search"
}'

Example - Performing a simple search.
No Ruby example available, showing cURL
curl -X POST 'https://host-2376rb.api.swiftype.com/api/as/v1/engines/ruby-gems/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer search-qcqrj73hmom796c98r22zeao' \
-d '{
  "query": "search"
}'

Example - Performing a simple search.
No Python example available, showing cURL
curl -X POST 'https://host-2376rb.api.swiftype.com/api/as/v1/engines/ruby-gems/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer search-qcqrj73hmom796c98r22zeao' \
-d '{
  "query": "search"
}'

Example - Performing a simple search.
No Javascript example available, showing cURL
curl -X POST 'https://host-2376rb.api.swiftype.com/api/as/v1/engines/ruby-gems/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer search-qcqrj73hmom796c98r22zeao' \
-d '{
  "query": "search"
}'

It is a big difference between returning something and returning the right thing. The name of the game is relevance. When we make a request, the Engine will send a response object in return. The response object contains a nested _meta object with a score key. The value of the score key is the relevance.

Consider that we host an application for finding useful RubyGems. The best search Gem of all - somehow, even better than App Search - is Searcheror Supreme. It is popular.

If we had basic search, a visitor querying for search would return Searcheror Supreme as one of the last results. That can lead to a poor experience - we want them to find the best Gem for their query.

The result of the search query would be:

{
   "name": {
     "raw": "Searcheror Supreme"
   },
   "id": {
     "raw": "1334"
   },
   "authors": {
     "raw": "Doctor Odd"
   },
   "downloads": {
     "raw": "421321431"
   },
   "info": {
     "raw": "A mind-bending experience of reclamation from the Ether. Not compatible with Dormammu Exiler."
   },
   "_meta": {
     "score": 4.986149
   }
 }

The relevance score under the _meta key is so low, a mere 5! Why is that?

By default, the Engine would take a uniform look across all fields for the keyword sent along with the query. The word search appears only once, as a part of the name Searcheror. Despite being the most popular Gem, the one that would give the visitor the better experience, it is buried under results that use the word search more often. This is not ideal! But this is how most search functions work.

To go deeper, you must write sophisticated algorithms. You would need to solve challenging data structure problems. But you already have a million things to build. Managing these deep search complexities is why Swiftype constructed App Search.

There are many different endpoints to help you craft a fast, imaginative and useful search experience. With the Search endpoint, you can apply the following features as arguments alongside your queries...

Feature Summary
Search Send in search queries. Search is where it all starts.
Search API Reference.
Search Fields Select which fields to search through and adjust the relevance weight across each field. Do visitors often just search via name? Is the info field not relevant? Adjust in accordance.
Search Fields API Reference | Relevance Tuning Guide.
Boosts What if a visitors seeks something new or blue or true? You can apply Boosts to queries to apply a uniform improvement on document relevance.
Boosts API Reference | Relevance Tuning Guide.
Grouping If results share the same the same field value, group them together. Return all cars or Gems or shoes grouped together by manufacturer, author or designer.
Grouping API Reference.
Result Field If you do not want to return all of the fields, you can get specific.
Result Field API Reference.
Facets Generate counts for a value or range belonging to each schema field.
Facets API Reference | Facets Guide
Sort Change the way results are sent, ascending or descending, for one or more fields.
Sorting API Reference.
Tags Apply tags for running Analytics against.
Tags API Reference.
Filters You have great control over how results are displayed. Filters get deep!
Filters API Reference.
API Logs You can see... everything!... Full transparency into any Engine-level request and response data.
API Logging Reference.

There are enough tools here that you can ensure the right content appears when a user conducts a search.

What is the difference between raw and snippet values?

A result can have a raw and/or snippet value:

  • raw: The default return format. Values are returned how they were indexed: a string, number or an array of strings and numbers.
  • snippet: A snippet is an escaped, browser friendly response. In many cases, it can be optimal to use the fallback option. If set to true, it will request a snippet but fallback to a raw response. If false, it will only provide snippets and never fallback to raw responses. Snippets are only available within text field types. The text value you searched for will return, highlighted by <em></em> tags.

Consider the security (XSS) risks when returning raw responses, then re-indexing those raw responses back into your documents without appropriate sanitization. Snippets will help address this, as will being mindful when using raw responses.

What about result meta data?

The meta key will be a JSON object containing information about the result set, such as:

  • request_id: A unique BSON id that coincides with each request. Each API request is logged within the API Log. The unique id will help you analyze requests.
  • warnings: As long as a request is formatted in the proper way, a status code of 200 will be returned. Warnings will inform you of issues within your queries.
  • page: Has four potential arguments...
Page Argument Detail
current Page number that is in the results field.
total_pages Number of of results available.
total_results Number of results that match the query.
size Number of results per page.

Why search?

The Internet offers information. A product, a thought -- whatever it may be, search can get people to the things they want, quicker. The faster they get there, the more likely they are to have an enjoyable experience and help you accomplish your business goals.

Where next?

You are now familiar with the basics of Search. Next, you can apply powerful tools to provide a relevant and valuable search experience. If you want to start polishing up how results appear, improving relevance and meeting business goals in the process, consider reading about Curations. If you want to see how your users search, consider diving into Analytics or Clickthrough. For the nitty-gritty details on the Search API, we have an API Reference.


Stuck? Looking for help? Contact Support!