> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Multiple consequences

> How to combine multiple Rules on the same query.

export const SearchQuery = () => <Tooltip tip="The text users enter into a search box. In the Search API, this corresponds to the query parameter. A search query is often used with filters, facets, and other parameters, but these aren't part of the query text itself.">
    search query
  </Tooltip>;

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

export const Filter = () => <Tooltip tip="A filter is a condition that limits which records Algolia returns. Filters often use one or more facet-value pairs, such as brand:Apple AND color:red. You can also filter by numeric values, dates, tags, booleans, or geographic constraints." cta="Filtering" href="/doc/guides/managing-results/refine-results/faceting">
    filter
  </Tooltip>;

export const Facet = () => <Tooltip tip="An attribute in your records that lets users filter or group results (for example, by color, brand, or price)." cta="Faceting" href="/doc/guides/managing-results/refine-results/faceting">
    facet
  </Tooltip>;

When creating a rule, **it's not uncommon to set more than one consequence**.
A good example is when you want to use a search term as a <Filter /> or a <Facet /> value but not for textual search.

Consider a website where users can search for movies by title, actor, or director. Some actors, like
Clint Eastwood are also directors: people searching for "clint eastwood" might not be looking for the same thing. For example, people looking only for movies directed by Clint Eastwood might search for "clint eastwood director",
hoping to filter out every movie that Clint Eastwood plays in but didn't direct.

In this case, you wouldn't be interested in the word "director for textual search purposes, but as a cue to set a filter.
You would therefore want to remove the word "director" from the <SearchQuery /> so that Algolia doesn't textually look for <Records /> matching that word.
You can achieve this by **combining several consequences in your rule**.

## Dataset example

In the following dataset, some movies have Clint Eastwood as an actor, some as a director, and some have both.

```json JSON icon=braces theme={"system"}
[
  {
    "title": "The Good, the Bad and the Ugly",
    "director": "Sergio Leone",
    "actors": ["Clint Eastwood", "Lee Van Cleef", "Elli Wallach"]
  },
  {
    "title": "Dirty Harry",
    "director": "Don Siegel",
    "actors": ["Clint Eastwood", "Andy Robinson", "Harry Guardino"]
  },
  {
    "title": "Million Dollar Baby",
    "director": "Clint Eastwood",
    "actors": ["Clint Eastwood", "Hilary Swank", "Morgan Freeman"]
  },
  {
    "title": "Invictus",
    "director": "Clint Eastwood",
    "actors": ["Morgan Freeman", "Matt Damon", "Tony Kgoroge"]
  }
]
```

If someone searches for
"clint eastwood", they would retrieve all movies by or with Clint Eastwood, even if they were only interested in movies with Clint Eastwood as the director. You could solve this problem with faceting, by setting `director` as an attribute for faceting and providing a refinement list with its own search input on your frontend.

Yet, an even better way of helping your users would be to make your search smart and look only for movies where `director` is equal to "Clint Eastwood" whenever they type "clint eastwood director". To achieve this, you first need to set `director` in your list of attributes for faceting. Then, you can create a new Rule that filters on matching attributes.

You need to create two consequences whenever a user types in "clint eastwood director":

* Filter all results with "director"
* Remove the word "director" from the search

## Using the API

To run the code examples on this page, [install the latest API client](/doc/libraries/sdk/install).

1. Set `director` as [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting). This happens at indexing time.
2. Set a Rule that:

   * Detects the term "director" in a query whenever it comes after a term that matches the name of a director
   * Applies a filter on facet value `director:'Clint Eastwood'`.

   To do this, use the [`saveRule`](/doc/libraries/sdk/v1/methods/save-rule) method.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings { AttributesForFaceting = new List<string> { "director" } }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      attributesForFaceting: [
        "director",
      ],
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetAttributesForFaceting(
      []string{"director"})))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings(
    "INDEX_NAME",
    new IndexSettings().setAttributesForFaceting(Arrays.asList("director"))
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'INDEX_NAME',
    indexSettings: { attributesForFaceting: ['director'] },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(attributesForFaceting = listOf("director")),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['attributesForFaceting' => [
          'director',
      ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "attributesForFaceting": [
              "director",
          ],
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(attributes_for_faceting: ["director"])
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        attributesForFaceting = Some(Seq("director"))
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(attributesForFaceting: ["director"])
  )
  ```
</CodeGroup>

However, setting the Rule isn't enough. Even when you set a Rule, the engine still tries to match the terms in the query. If a user searches for
"clint eastwood director",
even if your Rule applies, the engine will look for the word "director" in the records. With the example dataset, this would return no results at all. This is where combining consequences comes in handy.

When this Rule applies, you can add another consequence to remove the word "director" from the query. This way, the engine will only use it for filtering, not search.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SaveRuleAsync(
    "INDEX_NAME",
    "director-rule",
    new Rule
    {
      ObjectID = "director-rule",
      Conditions = new List<Condition>
      {
        new Condition
        {
          Pattern = "{facet:director} director",
          Anchoring = Enum.Parse<Anchoring>("Contains"),
        },
      },
      Consequence = new Consequence
      {
        Params = new ConsequenceParams
        {
          RestrictSearchableAttributes = new List<string> { "title", "book_id" },
          AutomaticFacetFilters = new AutomaticFacetFilters(
            new List<AutomaticFacetFilter> { new AutomaticFacetFilter { Facet = "director" } }
          ),
          Query = new ConsequenceQuery(
            new ConsequenceQueryObject
            {
              Edits = new List<Edit>
              {
                new Edit { Type = Enum.Parse<EditType>("Remove"), Delete = "director" },
              },
            }
          ),
        },
      },
    }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.saveRule(
    indexName: "INDEX_NAME",
    objectID: "director-rule",
    rule: Rule(
      objectID: "director-rule",
      conditions: [
        Condition(
          pattern: "{facet:director} director",
          anchoring: Anchoring.fromJson("contains"),
        ),
      ],
      consequence: Consequence(
        params: ConsequenceParams(
          restrictSearchableAttributes: [
            "title",
            "book_id",
          ],
          automaticFacetFilters: [
            AutomaticFacetFilter(
              facet: "director",
            ),
          ],
          query: ConsequenceQueryObject(
            edits: [
              Edit(
                type: EditType.fromJson("remove"),
                delete: "director",
              ),
            ],
          ),
        ),
      ),
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SaveRule(client.NewApiSaveRuleRequest(
    "INDEX_NAME", "director-rule",
    search.NewEmptyRule().SetObjectID("director-rule").SetConditions(
      []search.Condition{
        *search.NewEmptyCondition().SetPattern("{facet:director} director").SetAnchoring(search.Anchoring("contains")),
      }).
      SetConsequence(
        search.NewEmptyConsequence().SetParams(
          search.NewEmptyConsequenceParams().SetRestrictSearchableAttributes(
            []string{"title", "book_id"}).SetAutomaticFacetFilters(search.ArrayOfAutomaticFacetFilterAsAutomaticFacetFilters(
            []search.AutomaticFacetFilter{
              *search.NewEmptyAutomaticFacetFilter().SetFacet("director"),
            },
          )).SetQuery(search.ConsequenceQueryObjectAsConsequenceQuery(
            search.NewEmptyConsequenceQueryObject().SetEdits(
              []search.Edit{*search.NewEmptyEdit().SetType(search.EditType("remove")).SetDelete("director")})))))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.saveRule(
    "INDEX_NAME",
    "director-rule",
    new Rule()
      .setObjectID("director-rule")
      .setConditions(Arrays.asList(new Condition().setPattern("{facet:director} director").setAnchoring(Anchoring.CONTAINS)))
      .setConsequence(
        new Consequence().setParams(
          new ConsequenceParams()
            .setRestrictSearchableAttributes(Arrays.asList("title", "book_id"))
            .setAutomaticFacetFilters(
              AutomaticFacetFilters.ofListOfAutomaticFacetFilter(Arrays.asList(new AutomaticFacetFilter().setFacet("director")))
            )
            .setQuery(new ConsequenceQueryObject().setEdits(Arrays.asList(new Edit().setType(EditType.REMOVE).setDelete("director"))))
        )
      )
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.saveRule({
    indexName: 'indexName',
    objectID: 'director-rule',
    rule: {
      objectID: 'director-rule',
      conditions: [{ pattern: '{facet:director} director', anchoring: 'contains' }],
      consequence: {
        params: {
          restrictSearchableAttributes: ['title', 'book_id'],
          automaticFacetFilters: [{ facet: 'director' }],
          query: { edits: [{ type: 'remove', delete: 'director' }] },
        },
      },
    },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.saveRule(
      indexName = "INDEX_NAME",
      objectID = "director-rule",
      rule =
        Rule(
          objectID = "director-rule",
          conditions =
            listOf(
              Condition(
                pattern = "{facet:director} director",
                anchoring = Anchoring.entries.first { it.value == "contains" },
              )
            ),
          consequence =
            Consequence(
              params =
                ConsequenceParams(
                  restrictSearchableAttributes = listOf("title", "book_id"),
                  automaticFacetFilters =
                    AutomaticFacetFilters.ofListOfAutomaticFacetFilter(
                      listOf(AutomaticFacetFilter(facet = "director"))
                    ),
                  query =
                    ConsequenceQueryObject(
                      edits =
                        listOf(
                          Edit(
                            type = EditType.entries.first { it.value == "remove" },
                            delete = "director",
                          )
                        )
                    ),
                )
            ),
        ),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->saveRule(
      'INDEX_NAME',
      'director-rule',
      ['objectID' => 'director-rule',
          'conditions' => [
              ['pattern' => '{facet:director} director',
                  'anchoring' => 'contains',
              ],
          ],
          'consequence' => ['params' => ['restrictSearchableAttributes' => [
              'title',

              'book_id',
          ],
              'automaticFacetFilters' => [
                  ['facet' => 'director',
                  ],
              ],
              'query' => ['edits' => [
                  ['type' => 'remove',
                      'delete' => 'director',
                  ],
              ],
              ],
          ],
          ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.save_rule(
      index_name="INDEX_NAME",
      object_id="director-rule",
      rule={
          "objectID": "director-rule",
          "conditions": [
              {
                  "pattern": "{facet:director} director",
                  "anchoring": "contains",
              },
          ],
          "consequence": {
              "params": {
                  "restrictSearchableAttributes": [
                      "title",
                      "book_id",
                  ],
                  "automaticFacetFilters": [
                      {
                          "facet": "director",
                      },
                  ],
                  "query": {
                      "edits": [
                          {
                              "type": "remove",
                              "delete": "director",
                          },
                      ],
                  },
              },
          },
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.save_rule(
    "INDEX_NAME",
    "director-rule",
    Algolia::Search::Rule.new(
      algolia_object_id: "director-rule",
      conditions: [Algolia::Search::Condition.new(pattern: "{facet:director} director", anchoring: "contains")],
      consequence: Algolia::Search::Consequence.new(
        params: Algolia::Search::ConsequenceParams.new(
          restrict_searchable_attributes: ["title", "book_id"],
          automatic_facet_filters: [Algolia::Search::AutomaticFacetFilter.new(facet: "director")],
          query: Algolia::Search::ConsequenceQueryObject.new(
            edits: [Algolia::Search::Edit.new(type: "remove", delete: "director")]
          )
        )
      )
    )
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.saveRule(
      indexName = "INDEX_NAME",
      objectID = "director-rule",
      rule = Rule(
        objectID = "director-rule",
        conditions = Some(
          Seq(
            Condition(
              pattern = Some("{facet:director} director"),
              anchoring = Some(Anchoring.withName("contains"))
            )
          )
        ),
        consequence = Consequence(
          params = Some(
            ConsequenceParams(
              restrictSearchableAttributes = Some(Seq("title", "book_id")),
              automaticFacetFilters = Some(
                AutomaticFacetFilters(
                  Seq(
                    AutomaticFacetFilter(
                      facet = "director"
                    )
                  )
                )
              ),
              query = Some(
                ConsequenceQueryObject(
                  edits = Some(
                    Seq(
                      Edit(
                        `type` = Some(EditType.withName("remove")),
                        delete = Some("director")
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.saveRule(
      indexName: "INDEX_NAME",
      objectID: "director-rule",
      rule: Rule(
          objectID: "director-rule",
          conditions: [SearchCondition(
              pattern: "{facet:director} director",
              anchoring: SearchAnchoring.contains
          )],
          consequence: SearchConsequence(params: SearchConsequenceParams(
              restrictSearchableAttributes: ["title", "book_id"],
              query: SearchConsequenceQuery
                  .searchConsequenceQueryObject(SearchConsequenceQueryObject(edits: [SearchEdit(
                      type: SearchEditType.remove,
                      delete: "director"
                  )])),
              automaticFacetFilters: SearchAutomaticFacetFilters
                  .arrayOfSearchAutomaticFacetFilter([SearchAutomaticFacetFilter(facet: "director")])
          ))
      )
  )
  ```
</CodeGroup>

## Using the dashboard

You can also add your Rules in Algolia's dashboard.

1. Select the **Search** product icon on your dashboard and then select your <Index />.

2. Click the **Configuration** tab.

3. In the **Facets** subsection of Filtering and Faceting, click the "Add an attribute" button and select the `director` attribute from the drop-down menu.

4. Select the **Rules** section from the left sidebar menu in the [Algolia dashboard](https://dashboard.algolia.com/rules).

5. Under the heading **Rules**, select the index to which you're adding a Rule.

6. Select **Create your first rule** or **New rule**. In the dro-down menu, click the **Manual Editor** option.

7. In the **Condition(s)** section, keep **Query** toggled on, select **Contains** in the drop-down menu, and select the option **Add Facet "director"** from the input box. `{facet:director}` should then be displayed.

8. In the **Consequence(s)** section:

   * Click the **Add consequence** button and select **Filter Matching Attributes** (or **Filter/Boost Matching Attributes**).
   * In the **Filter** input that appears, select the option **Add Facet "director"** in the drop-down menu.
   * Click the **Add consequence** button again and select **Remove Word**.
   * In the input that appears, select **Remove `{facet:director}`**.

9. Save your changes.
