megachangelog
Feature1.55.0

v1.55.0: Dynamic search rule preview and facet performance details

Added support for inline dynamic search rules that preview rule effects on individual queries, and enhanced performance details to show facet distribution computation timing. The inlineRule parameter allows applying temporary rule overrides during search without persisting them, useful for preview UIs.

🌈 Improvements

Preview the effect of a dynamic search rule

Apply an inline-specified dynamic search rule to a search query.

Search query objects in the following endpoints now have an additional, optional inlineRule parameter.

When present and not null, then Meilisearch will check if query satisfies the conditions of the dynamic search rule specified in inlineRule, and if so will apply the actions of the rule as if it had been sent to the PATCH /dynamicSearchRule/{:uid} endpoint.

Additionally, if the Meili-Include-Metadata header is present in the request with the value true, then the metadata in the response will contain information about whether the conditions of the inline rule were satisfied and if not why.

Meilisearch Cloud will use this backend feature to implement a preview UI for dynamic search rules.

Using inlineRule requires Meilisearch Enterprise Edition and the dynamicSearchRules experimental feature.

By @dureuill in #6669

Details

  1. There is a new InlineRule object with the following field:
    1. uid, string, mandatory: unique ID of the rule. If there is already a rule with this id, then the inline rule will replace the existing rule for the duration of this search query.
    2. active, boolean, optional, defaults to true: whether the rule is active. The actions of an inactive inline rule never apply to the search, but its conditions are still checked
    3. conditions: RuleConditions object, identical to the conditions field in the body of PATCH /dynamic-search-rules/{:uid}
    4. actions: RuleActions object, identical to the actions field in the body of PATCH /dynamic-search-rules/{:uid}
    5. precedence: integer, optional, identical to the precedence field in the body of PATCH /dynamic-search-rules/{:uid}
  2. The POST /indexes/{:indexUid}/search body has an additional, optional (defaults to null) inlineRule field which is an InlineRule object.
  3. In the POST /multi-search body, the objects inside the queries array have an additional, optional (defaults to null) inlineRule field which is an InlineRule object.

Examples

Passing a search rule specific to the user making the request
// POST /indexes/movies/search
{
  "q": "super hero",
  "inlineRule": {
    "uid": "user-likes-batman",
    "actions": {
      "scale": [
        {
          // filter recent Batman movies
          "filter": "hero = batman AND release_time = fresh",
          "weight": 1.2 // moderate relevancy boost
        }
      ]
    }
  }
}
Previewing the effect of a search rule
// POST /multi-search -H 'Meili-Include-Metadata: true`

{
  "queries": [
    // base query without inline rule
    {
      "q": "fashion",
      "filter": "color = blue AND category = shirt"
    },
    // same query with inline rule
    {
      "q": "fashion",
      "filter": "color = blue AND category = shirt",
      "inlineRule": {
        "uid": "special-sales",
        "conditions": {
          "query": {
            "words": "pants",
          },
            "filter": {
              "values": {
                "color":  "yellow",
                "stock_intent": "destock"
            }
          }
        }
      }
    }
  ]
}

Response:

{
  // [ ... ] some other fields
  "results": [
    // results without the rule
    {
      "hits": [ ... ] // documents returned without the rule
    },
    // results with the rule
    {
      // [...] some other fields
      "hits": [...], // documents returned with the rule. Here the same, because the conditions of the rules are not satisfied
      "metadata": {
        // [...] some other fields
        "inlineRuleConditionOutcomes":  {
          "satisfiesActiveCondition": true,
          "satisfiesQueryWordsCondition": {
            "missingWord": "pants"
          },
        "satifiesFilterCondition": {
          "missingConstraintOnField": {
            "field":  "stock_intent"
          },
          "unmetConstraintOnField": 
            "field": "color"
          }
        }
      }
    }
  ]
}

Improve showPerformanceDetails at search time

When setting showPerformanceDetails to true in a search request, the response's performanceDetails will now display an entry for the facet distribution computation.

New trace entries

Request

curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -d '{
    "q": "batman",
    "facets": ["genres"],
    "showPerformanceDetails": true,
    "limit": 3
  }'

Response

{
    "hits": [
		# ...
    ],
    "query": "batman",
    "processingTimeMs": 4,
    "limit": 3,
    "offset": 0,
    "estimatedTotalHits": 68,
    "facetDistribution": {
        "genres": {
			#...
        }
    },
    "facetStats": {},
    "requestUid": "01a12f80-0e1b-7632-b4f3-c8d4914048c9",
    "performanceDetails": {
        "wait in queue": "68.58µs",
        "preprocess filters > prepare": "100.25µs",
        "preprocess filters": "100.42µs",
        "process > prepare": "115.54µs",
        "process > send to remote": "102.71µs",
        "process > execute local > load field ids map": "30.88µs",
        "process > execute local > query[0] > tokenize query": "265.38µs",
        "process > execute local > query[0] > evaluate query": "890.96µs",
        "process > execute local > query[0] > keyword ranking": "425.04µs",
        "process > execute local > query[0]": "2.95ms",
        "process > execute local > pin hits": "9.92µs",
        "process > execute local > format": "94.62µs",
        "process > execute local > facet distribution > compute facet distribution": "315.75µs",
        "process > execute local > facet distribution > compute facet stats": "27.71µs",
        "process > execute local > facet distribution": "432.62µs",
        "process > execute local": "3.81ms",
        "process > wait for remote": "50.96µs",
        "process > merge": "905.62µs",
        "process": "5.07ms"
    }
}

Three additional steps:

        "process > execute local > facet distribution > compute facet distribution": "315.75µs",
        "process > execute local > facet distribution > compute facet stats": "27.71µs",
        "process > execute local > facet distribution": "432.62µs",

By @ManyTheFish in #6644

🦋 Fixes

Avoid panic at search time during formatting

Documents containing raw unicode codepoints (e.g. \u03b1) would cause a panic at search time when formatting results for highlighting when using some segmenters.

A failure at the segmenter's level no longer causes a panic.

By @dureuill in #6673

Fix search performance of ranking score threshold

Important

This fix modifies the relevancy of the engine in some circumstances. This is allowed as per our back-compatiblity policy.

To avoid a performance sink when using the rankingScoreThreshold parameter in a search, Meilisearch now guarantees that the search will stop after evaluating the first document whose score is below the threshold. Previously Meilisearch would try to evaluate more documents, which could lead to evaluating all documents in the database, causing a very long search time.

By @ManyTheFish in #6661

Prevent unsupported binaryQuantization deactivation in embedder settings

Warning

This fix introduces a breaking change in the Meilisearch API. Because the previous behavior would corrupt the embeddings in the database, this is allowed by our back-compatibility policy.

Since the exact value of embeddings is not retained when the embedder is configured for binary quantize embeddings, disabling the binary quantization on an index is not allowed.

Unfortunately, an oversight in the API allowed to accidentally disable binary quantization by passing binaryQuantization: null in a setting update. This now results in an error.

By @dureuill in #6656

🔩 Miscellaneous

Full Changelog: v1.54.3...v1.55.0

search-apidynamic-rulesperformancefacetsenterprise

Source: original entry ↗

More from Meilisearch

Follow Meilisearch to get its new changes in your feed and email digest.

Fix1.53.3

Avoid panic in highlighting with safer indexing

Replaced unsafe bracket indexing with get method and added None recovery in the highlighting logic to prevent panics. This improves stability when processing edge cases in search result highlighting.

highlightingstabilityfix
Fix1.53.3

Stability fix for Meilisearch

This release addresses an important stability issue. Users on v1.53.2 are recommended to update.

stabilitybugfixcore
See all Meilisearch changes →