Oihana PHP Arango

aqlScoredSearch.php

Table of Contents

Functions

aqlScoredSearch()  : string
Builds a complete, relevance-ranked AQL search query over an ArangoSearch View.

Functions

aqlScoredSearch()

Builds a complete, relevance-ranked AQL search query over an ArangoSearch View.

aqlScoredSearch(string $view, string|array<string|int, mixed> $search, int $limit[, string|null $analyzer = null ][, array<string|int, mixed>|object|string|null $options = null ][, string $scorer = SearchScorer::BM25 ][, float|null $k = null ][, float|null $b = null ][, bool|null $normalize = null ][, int $offset = 0 ][, string $docRef = 'doc' ][, string $scoreRef = 'score' ][, string|null $return = null ]) : string

The generated query follows the canonical scored-search form:

FOR <docRef> IN <view>
  SEARCH <expression> [OPTIONS { … }]
  LET <scoreRef> = BM25(<docRef>) | TFIDF(<docRef>)
  SORT <scoreRef> DESC
  LIMIT [<offset>,] <limit>
  RETURN <return>

Both scorers rank better matches with higher values, so the sort is always descending — there is no direction to get wrong. The score is bound to a LET variable ($scoreRef, default score) so a custom $return expression can expose it, e.g. 'MERGE(doc, { score: score })'.

The SEARCH segment reuses aqlFor() / aqlSearch(): the optional $analyzer wraps the expression in ANALYZER(expr, "name") and the optional $options becomes the SEARCH … OPTIONS { … } object (hydrated into SearchOptions).

The scorer functions require the indexed fields' Analyzers to have the "frequency" feature enabled (and "norm" for meaningful BM25 length normalization), otherwise the score is 0.

Example: phrase search ranked by BM25

use function oihana\arango\db\functions\search\phrase;
use function oihana\arango\db\operations\aqlScoredSearch;

$aql = aqlScoredSearch
(
    view     : 'placesView' ,
    search   : phrase( 'doc.name' , 'scierie' ) ,
    limit    : 20 ,
    analyzer : 'text_fr' ,
) ;
// FOR doc IN placesView SEARCH ANALYZER(PHRASE(doc.name,"scierie"),"text_fr")
//   LET score = BM25(doc) SORT score DESC LIMIT 20 RETURN doc

Example: TF-IDF, pagination, and the score in the output

$aql = aqlScoredSearch
(
    view      : 'articlesView' ,
    search    : 'doc.text IN TOKENS(@q, "text_en")' ,
    limit     : 10 ,
    offset    : 20 ,
    scorer    : SearchScorer::TFIDF ,
    normalize : true ,
    return    : 'MERGE(doc, { score: score })' ,
) ;
// FOR doc IN articlesView SEARCH doc.text IN TOKENS(@q, "text_en")
//   LET score = TFIDF(doc,true) SORT score DESC LIMIT 20, 10 RETURN MERGE(doc, { score: score })
Parameters
$view : string

The ArangoSearch View to query.

$search : string|array<string|int, mixed>

The SEARCH expression (kept raw; arrays are compiled like AQL::SEARCH).

$limit : int

The maximum number of matches to return (the LIMIT).

$analyzer : string|null = null

Optional Analyzer name wrapping the expression in ANALYZER(expr, "name").

$options : array<string|int, mixed>|object|string|null = null

Optional SEARCH … OPTIONS { … } object (see aqlSearch()).

$scorer : string = SearchScorer::BM25

The scoring algorithm: SearchScorer::BM25 (default) or SearchScorer::TFIDF.

$k : float|null = null

Optional BM25 term-frequency calibration (BM25 only).

$b : float|null = null

Optional BM25 text-length scaling (BM25 only).

$normalize : bool|null = null

Optional TF-IDF score normalization (TFIDF only).

$offset : int = 0

Optional number of matches to skip (pagination).

$docRef : string = 'doc'

The iteration variable name (default 'doc').

$scoreRef : string = 'score'

The LET score variable name (default 'score').

$return : string|null = null

Optional RETURN expression. Defaults to the iteration variable.

Tags
throws
BindException
ReflectionException

If the search options hydration fails.

see
https://docs.arangodb.com/stable/aql/functions/arangosearch/#scoring-functions
SearchScorer
aqlSearch()
bm25()
tfidf()
since
1.2.0
author

Marc Alcaraz

Return values
string

The complete AQL scored-search query.

On this page

Search results