---
title: Multi-warehouse Search
description: How to scope search ranking per warehouse using context parameters.
slug: solutions/multi-warehouse
docKind: solution
hub: solutions
---

Most ecommerce businesses use several geographically distributed warehouses but the underlying warehousing infrastructure is transparent to the end users. They simply interact with the store, place an order and the order is delivered to them from one of the warehouses.

For some businesses however, the concept of the warehouse is an integral part of their business and the users are aware of the warehouse and frequently, they choose the warehouse that they want to use for their delivery. This will typically be B2B commerces, online groceries, or in general, business, where speed of delivery is of utmost importance.

The requirements for this scenario are usually:

- User selects one of the available warehouses in the user interface (or the warehouse is selected automatically by the system)
- Several aspects of the products, most notably _availability_ of the products are considered in the context of the selected warehouse

The important aspect of a multi-warehouse solution is that it is not a simple display problem. The underlying models have to obey the warehouse-related product data when applying [Ranking rules](/search/guides/ranking/).

Luigi's Box Autocomplete and Search are designed to let you plug in your own attributes which drive the underlying ranking models and getting a warehouse-scoped ranking.

## Availability and availability rank

By plugging in a warehouse-related availability attribute, you can instruct the ranking model to use that attribute for product availability when ranking.

Consider two products with the following data

```javascript
// Product #1
{
  "title": "Product #1",
  "availability_warehouse_1": 1,  // available in warehouse 1
  "availability_warehouse_2": 0   // not available in warehouse 2
}

// Product #2
{
  "title": "Product #2",
  "availability_warehouse_1": 0,  // not available in warehouse 1
  "availability_warehouse_2": 1   // available in warehouse 2
}
```

You can then use the availability [Context parameter](/search/api/v1/search/) to instruct the ranking model to consider product availability at warehouse 1 by setting `context[availability_field]=availability_warehouse_1`.

Since the default [Ranking](/search/guides/ranking/) prefers available products, if you issue an API request with `context[availability_field]=availability_warehouse_1`, the API would return products in the order:

- Product #1
- Product #2

If you switch availability context to warehouse 2 and issue an API request with `context[availability_field]=availability_warehouse_2`, the API would return products in the order:

- Product #2
- Product #1

Similarly to `context[availability_field]`, use `context[availability_rank_field]` to plug in the warehouse-scoped Availability rank attribute to use for ranking.

## Boosting

The Boost attribute can be used to specify product boosting when indexing data. You can plug in a warehouse-scoped boost attribute to drive boosting per-warehouse.

Use the boosting context to set up different product promotions across different warehouses.

```javascript
// Product #1
{
  "title": "Product #1",
  "availability_warehouse_1": 1,
  "availability_warehouse_2": 1,
  "boost_warehouse_1": 1          // Boost this product in warehouse 1
}

// Product #2
{
  "title": "Product #2",
  "availability_warehouse_1": 1,
  "availability_warehouse_2": 1,
  "boost_warehouse_2": 1           // Boost this product in warehouse 2
}
```

You can then use the boost [Context parameter](/search/api/v1/search/) to instruct the ranking model to consider product boost at warehouse 1 by setting `context[boost_field]=boost_warehouse_1`.

## Freshness (introduced at)

The Introduced at attribute can be used to drive the concept of freshness in the ranking model. If the products are being introduced to different warehouses at different times, you can use the freshness [Context parameter](/search/api/v1/search/) to adapt the ranking model to a specific warehouse.

```javascript
// Product #1
{
  "title": "Product #1",
  "availability_warehouse_1": 1,
  "availability_warehouse_2": 1,
  "introduced_at_warehouse_1": "2023-11-30", // Newer at warehouse 1
  "introduced_at_warehouse_2": "2023-11-23"
}

// Product #2
{
  "title": "Product #2",
  "availability_warehouse_1": 1,
  "availability_warehouse_2": 1,
  "introduced_at_warehouse_1": "2023-11-23",
  "introduced_at_warehouse_2": "2023-11-30" // Newer at warehouse 2
}
```

## Put it all together

In practice, you will only rarely use all of the context fields at once. Start by identifying what are the attributes that should affect the ranking at the warehouse level and make sure that you are indexing these attribute at the product level for each warehouse.

When making requests to [Search](/search/api/v1/search/) or [Autocomplete](/autocomplete/api/v2/autocomplete/) API, set the context fields to the warehouse fields storing data for the warehouse the user selected. In terms of code, you will most likely just interpolate the warehouse ID into the request:

```javascript
`&context[availability_field]=availability_warehouse_${current_user_warehouse_id}&context[freshness_field]=introduced_at_warehouse_${current_user_warehouse_id}`;
```

## Feeds versus API

This solution and the context fields in general are agnostic of the indexing method. The solution will work the same whether you are using [Feeds](/indexing/feeds/) or [API](/indexing/api/v1/content-update/) to index the data.

## Constrain the feedback loop

If by the nature of your business the users behave very differently across different warehouses, you can force Luigi's Box to create several ranking models for every warehouse. Note that this is a very advanced use case and you should consider the implications before you proceed with the integration. By splitting the model into several smaller models you are making each model slightly less robust, since it will get exposed to less behavioral data.

Creation of the models is driven by the context in the analytics data. Note that since _contexts_ are an advanced feature, the _context_ is currently only supported when pushing analytics events via API.

To create a separate ranking model for each of your warehouses, start by adding a `context` parameter to the analytics events.

```javascript
  "context": {
    "warehouse": "Berlin"
  }
```

This will create a separate model for each warehouse in the background and each events will contribute to the warehouse-specific model.

To use the model in the retrieval APIs, specify the `ctx` key/value parameter in the API request:

`&ctx[]=warehouse:Berlin`

The model selection (the `ctx` parameter) is supported in:

- [Autocomplete API](/autocomplete/api/v2/autocomplete/)
- [Search API](/search/api/v1/search/)
- [Top items](/autocomplete/api/v1/top-items/)
