1. Getting Started
  2. Search

Getting Started

Search

Most of PackageX's list APIs support search. This is a generic query parameter that matches against certain indexed properties of the resource.

PackageX supports a legacy search feature and an advanced search feature. Advanced search is currently available for:

  • Contacts
  • Shipments/Deliveries
  • Shipping Label Inferences
  • Uses query string parameter search
  • Each terms in the search query must be at least 2 characters
  • Results include resource where any of the searched terms match
  • In the response, each resource object has a key _search with the relevance score and the indexed search properties.
  • Unless an order_by parameter is explicitly passed in the request, results are sorted with the most relevant resource being at the top

e.g. GET /v1/contacts?search=hello

With advanced search, you have a lot more control of how the search can be conducted. The behavior of legacy search is preserved, so using search in the query string parameters will still perform the general search, and _search key will still be present in the response. However, _search does not have any relevance to the ordering of the results.

With advanced search, you can perform general search, or targeted search across the resource's searchable properties, or a mixture of both.

Please keep in mind that using search will set the ignore page sizes above 100.

Response Model

For all list APIs with support for advanced search, there is a top-level key in the response model called search with the following structure:

        {
  {
    queries: Record<
      string,
      {
        query: null | string;
        operator: "AND" | "OR" | null;
        mode: "search" | "highlight";
        boost: 0.0 | 0.25 | 0.5 | 0.75 | 1.0 | 1.25 | 1.5 | 2.0 | 4.0 | 8.0;
        type: "fuzzy" | "prefix" | "hybrid";
      }
    >;
    terms: string;
    type: "fuzzy" | "prefix" | "hybrid" | "auto";
  }
}

      

Lets go one-by-one over each of these:

  • terms is a space separated list of all the terms specified by the user which are included in the actual search queries performed, even if multiple fields are searched (more on this in the Targeted Search section)
  • type is the overall type of search that is to be done. Defaults to auto
    • fuzzy: only fuzzy searching is done
    • prefix: only prefix matching is done
    • hybrid: both fuzzy and prefix matching are attempted
    • auto: currently, this is used as a placeholder for hybrid
  • queries breaks down how the various search parameters are interpreted by the system for each indexed search field:
    • query: the interpreted query. Can be null when mode is highlight instead of the default search
    • operator: whether all or any of the terms in the query need to be present for a match. defaults to OR
    • mode: whether to search (will affect the results) or just highlighted matching content (but not affect the results)
    • boost: relative boosting applied to the current indexed field. Defaults to 1. This affects both the relevance and similarity scores (more on this later)
    • type: the type of search performed for the current indexed field

Resource _searchV2

Each resource object in the top-level data array of the response has a _searchV2 key with the following structure:

scores object

An object representing the various scores calculated

Show Details
scores._relevance number
The relevance score returned from the search engine. This is affected by boost. This in an unbounded number
scores._similarity number
A score between 0 and 1 representing the similarity if the search query terms with highlighted content
scores._coverage number
Length of uniquely highlighted/matched content across all indexed properties where matches occur. This means e.g. a certain string is highlighted in both name and email, it will only be counted once.
scores._uncoverage number
The total length of all uniquely unhighlighted/unmatched content across all indexed properties where matched occur

contact|shipment|shipping_label_inference object
The key here is dynamic and changes depending on the resource being searched. Its structure is a subset of the actual resource with only those keys and nesting present where there is some highlighted content.

Request

The following keys are applicable to all resources with advanced search:

  • search: a string with one or more terms where each term must be at least 2 characters long. This performs a general search across all the searchable properties of a resource.
  • order_by: an optional string whose values depend on the resource being queried. But for search purposes, when this is not specified, results are ordered by the relevance score from the search engine, which is an unbounded number. Some applicable values across all resource when talking about search:
    • this can be explicitly set as order_by=_relevance to ensure that results are always ordered by search engines relevance
    • you can also order results by similarity to the search terms. This can be done by order_by=_similarity. Similarity is a number between 0 and 1 which tells us how close the search terms are to the highlighted content for the indexed search properties of the resource.
  • search_operator: AND|OR. Defaults to OR. Whether all or any of the terms in the various search fields need to be present for a match. Can override this for each searchable property (this is resource dependent).
  • search_type: fuzzy|prefix|hybrid|auto. Default to auto:
    • fuzzy: only fuzzy searching is done
    • prefix: only prefix matching is done
    • hybrid: both fuzzy and prefix matching are attempted
    • auto: currently, this is used as a placeholder for hybrid
  • search_combined_operator: AND|OR. Defaults to AND. When doing targeted search, whether matches must be found in all (AND) or any (OR) of the search fields provided.

Whenever search parameter is used, a generic search is performed where the query terms are searched across all the indexed fields of the resource

This is resource specific and details are given for each resource supporting advanced search in the respective section. Here, we will use a simple contact example.

Assume that we have these indexed fields for a contact:

  • name: primary name of the contact
  • names: all the names (alternative, nickname, primary) of the contact
  • email: primary email of the contact
  • emails: all the emails (alternative, nickname, primary) of the contact

Assume this is the data hat is present:

        [
  { "name": "Jamie Jones", "email": "jamie.jones@foo.com" },
  { "name": "Jamis Doe", "email": "jamis.doe@bar.com" },
  { "name": "Jane Doe", "email": "jamie.doe@bar.com" },
  { "name": "John Jones", "email": "john@foo.com" }
]

      

So using search=Jamie will look for jamie in all these fields. This is an example of the results you can get:

        [
  { "name": "Jamie Jones", "email": "jamie.jones@foo.com" },
  { "name": "Jamis Doe", "email": "jamis.doe@bar.com" },
  { "name": "Jane Doe", "email": "jamie.doe@bar.com" }
]

      

Jamis is returned due to fuzzy matching

Now assume you are only interested in doing a primary name search. You can use search.name=Jamie. This will only return:

        [
  { "name": "Jamie Jones", "email": "jamie.jones@foo.com" },
  { "name": "Jamis Doe", "email": "jamis.doe@bar.com" }
]

      

Now lets say you want to get a contact whose name includes Jamie and email has foo.com. You can use search.name=Jamie&search.email=foo.com.

Now lets say you want to get a contact whose name includes Jamie or email has foo.com. You can use search.name=Jamie&search.email=foo.com&search_combined_operator=OR.

Modifiers

The following modifiers are available for each of the indexed fields of the resource:

  • *.operator: AND|OR. Defaults to OR. Whether all or any of the terms in the targeted query need to be present for a match. Defaults the global search.operator, which defaults to OR if not provided.
  • *.boost: 0|0.25|0.5|0.75|1|1.25|1.5|2|4|8. Relative boosting applied to the current indexed field. Defaults to 1.
  • *.mode: search|highlight whether to search (will affect the results) or just highlighted matching content (but not affect the results)

So with the example where our fields are name,names,email and emails, these will translate to these optional modifiers:

  • search.name.operator
  • search.names.operator
  • search.email.operator
  • search.emails.operator
  • search.name.boost
  • search.names.boost
  • search.email.boost
  • search.emails.boost
  • search.name.mode
  • search.names.mode
  • search.email.mode
  • search.emails.mode

You can use these modifiers without using targeted search and with general search. For e.g. search=jamie foo&search.names.boost=4 will perform a general search returning results where jamie or foo or both are found in any of the indexed fields, but it will give 4X more weightage to names as compared to other fields where matches are found.

Metadata

You can perform a general metadata search using search.metadata query string parameter

You can also perform a targeted metadata search e.g. lets say there is a metadata key call building. You can do search.metadata.building=hq. Please note that periods (.) are not allowed withing metadata keys.

All modified available for indexed fields are also available for metadata.

Additionally, multiple metadata filters are available for all resource supporting advanced search.