php - Undefined array key "docScores"

one text

I'm working with the scout library and the tntsearch driver but when I try to search for a word that is in the website I get the error in the title. The code part where the error is according to Laravel is the one below and the line is the one between **. Do you have any idea on how to solve this? Thanks!

 public function map(Builder $builder, $results, $model)
{
    if (empty($results['ids'])) {
        return $model->newCollection([]);
    }

    $keys = collect($results['ids'])->values()->all();

    $builder = $this->getBuilder($model);

    if ($this->builder->queryCallback) {
        call_user_func($this->builder->queryCallback, $builder);
    }

    $models = $builder->whereIn(
        $model->getQualifiedKeyName(), $keys
    )->get()->keyBy($model->getKeyName());

    // sort models by user choice
    if (!empty($this->builder->orders)) {
        return $models->values();
    }

    // sort models by tnt search result set
    return $model->newCollection(collect($results['ids'])->map(function ($hit) use ($models, $results) {
        if (isset($models[$hit])) {
           *return $models[$hit]->setAttribute('__tntSearchScore__', $results['docScores'][$hit]);*
        }
    })->filter()->all());
}

This is the whole page of code:

class TNTSearchEngine extends Engine

{

private $filters;
/**
 * @var TNTSearch
 */
protected $tnt;

/**
 * @var Builder
 */
protected $builder;

/**
 * Create a new engine instance.
 *
 * @param TNTSearch $tnt
 */
public function __construct(TNTSearch $tnt)
{
    $this->tnt = $tnt;
}

public function getTNT()
{
    return $this->tnt;
}

/**
 * Update the given model in the index.
 *
 * @param Collection $models
 *
 * @return void
 */
public function update($models)
{
    $this->initIndex($models->first());
    $this->tnt->selectIndex("{$models->first()->searchableAs()}.index");
    $index = $this->tnt->getIndex();
    $index->setPrimaryKey($models->first()->getKeyName());

    $index->indexBeginTransaction();
    $models->each(function ($model) use ($index) {
        $array = $model->toSearchableArray();

        if (empty($array)) {
            return;
        }

        if ($model->getKey()) {
            $index->update($model->getKey(), $array);
        } else {
            $index->insert($array);
        }
    });
    $index->indexEndTransaction();
}

/**
 * Remove the given model from the index.
 *
 * @param Collection $models
 *
 * @return void
 */
public function delete($models)
{
    $this->initIndex($models->first());
    $models->each(function ($model) {
        $this->tnt->selectIndex("{$model->searchableAs()}.index");
        $index = $this->tnt->getIndex();
        $index->setPrimaryKey($model->getKeyName());
        $index->delete($model->getKey());
    });
}

/**
 * Perform the given search on the engine.
 *
 * @param Builder $builder
 *
 * @return mixed
 */
public function search(Builder $builder)
{
    try {
        return $this->performSearch($builder);
    } catch (IndexNotFoundException $e) {
        $this->initIndex($builder->model);
    }
}

/**
 * Perform the given search on the engine.
 *
 * @param Builder $builder
 * @param int     $perPage
 * @param int     $page
 *
 * @return mixed
 */
public function paginate(Builder $builder, $perPage, $page)
{
    $results = $this->performSearch($builder);

    if ($builder->limit) {
        $results['hits'] = $builder->limit;
    }

    $filtered = $this->discardIdsFromResultSetByConstraints($builder, $results['ids']);

    $results['hits'] = $filtered->count();

    $chunks = array_chunk($filtered->toArray(), $perPage);

    if (empty($chunks)) {
        return $results;
    }

    if (array_key_exists($page - 1, $chunks)) {
        $results['ids'] = $chunks[$page - 1];
    } else {
        $results['ids'] = [];
    }

    return $results;
}

/**
 * Perform the given search on the engine.
 *
 * @param Builder $builder
 *
 * @return mixed
 */
protected function performSearch(Builder $builder, array $options = [])
{
    $index = $builder->index ?: $builder->model->searchableAs();
    $limit = $builder->limit ?: 10000;
    $this->tnt->selectIndex("{$index}.index");

    $this->builder = $builder;

    if (isset($builder->model->asYouType)) {
        $this->tnt->asYouType = $builder->model->asYouType;
    }

    if ($builder->callback) {
        return call_user_func(
            $builder->callback,
            $this->tnt,
            $builder->query,
            $options
        );
    }

    $builder->query = $this->applyFilters('query_expansion', $builder->query, get_class($builder->model));

    if (isset($this->tnt->config['searchBoolean']) ? $this->tnt->config['searchBoolean'] : false) {
        $res = $this->tnt->searchBoolean($builder->query, $limit);
        event(new SearchPerformed($builder, $res, true));
        return $res;

    } else {
        $res = $this->tnt->search($builder->query, $limit);
        event(new SearchPerformed($builder, $res));
        return $res;
    }
}

/**
 * Map the given results to instances of the given model.
 *
 * @param mixed                               $results
 * @param \Illuminate\Database\Eloquent\Model $model
 *
 * @return Collection
 */
public function map(Builder $builder, $results, $model)
{
    if (empty($results['ids'])) {
        return $model->newCollection([]);
    }

    $keys = collect($results['ids'])->values()->all();

    $builder = $this->getBuilder($model);

    if ($this->builder->queryCallback) {
        call_user_func($this->builder->queryCallback, $builder);
    }

    $models = $builder->whereIn(
        $model->getQualifiedKeyName(), $keys
    )->get()->keyBy($model->getKeyName());

    // sort models by user choice
    if (!empty($this->builder->orders)) {
        return $models->values();
    }

    // sort models by tnt search result set
    return $model->newCollection(collect($results['ids'])->map(function ($hit) use ($models, $results) {
        if (isset($models[$hit])) {
            return $models[$hit]->setAttribute('__tntSearchScore__', $results['docScores'][$hit]);
        }
    })->filter()->all());
}

/**
 * Map the given results to instances of the given model via a lazy collection.
 *
 * @param mixed                               $results
 * @param \Illuminate\Database\Eloquent\Model $model
 *
 * @return LazyCollection
 */
public function lazyMap(Builder $builder, $results, $model)
{
    if (empty($results['ids'])) {
        return LazyCollection::make();
    }

    $keys = collect($results['ids'])->values()->all();

    $builder = $this->getBuilder($model);

    if ($this->builder->queryCallback) {
        call_user_func($this->builder->queryCallback, $builder);
    }

    $models = $builder->whereIn(
        $model->getQualifiedKeyName(), $keys
    )->get()->keyBy($model->getKeyName());

    // sort models by user choice
    if (!empty($this->builder->orders)) {
        return $models->values();
    }

    // sort models by tnt search result set
    return $model->newCollection($results['ids'])->map(function ($hit) use ($models) {
        if (isset($models[$hit])) {
            return $models[$hit];
        }
    })->filter()->values();
}

/**
 * Return query builder either from given constraints, or as
 * new query. Add where statements to builder when given.
 *
 * @param \Illuminate\Database\Eloquent\Model $model
 *
 * @return Builder
 */
public function getBuilder($model)
{
    // get query as given constraint or create a new query
    $builder = isset($this->builder->constraints) ? $this->builder->constraints : $model->newQuery();

    $builder = $this->handleSoftDeletes($builder, $model);

    $builder = $this->applyWheres($builder);

    $builder = $this->applyOrders($builder);

    return $builder;
}

/**
 * Pluck and return the primary keys of the given results.
 *
 * @param mixed $results
 * @return \Illuminate\Support\Collection
 */
public function mapIds($results)
{
    if (empty($results['ids'])) {
        return collect();
    }

    return collect($results['ids'])->values();
}

/**
 * Get the total count from a raw result returned by the engine.
 *
 * @param mixed $results
 *
 * @return int
 */
public function getTotalCount($results)
{
    return $results['hits'];
}

public function initIndex($model)
{
    $indexName = $model->searchableAs();

    if (!file_exists($this->tnt->config['storage']."/{$indexName}.index")) {
        $indexer = $this->tnt->createIndex("$indexName.index");
        $indexer->setDatabaseHandle($model->getConnection()->getPdo());
        $indexer->setPrimaryKey($model->getKeyName());
    }
}

/**
 * The search index results ($results['ids']) need to be compared against our query
 * that contains the constraints.
 *
 * To get the correct results and counts for the pagination, we remove those ids
 * from the search index results that were found by the search but are not part of
 * the query ($sub) that is constrained.
 *
 * This is achieved with self joining the constrained query as subquery and selecting
 * the ids which are not matching to anything (i.e., is null).
 *
 * The constraints usually remove only a small amount of results, which is why the non
 * matching results are looked up and removed, instead of returning a collection with
 * all the valid results.
 */
private function discardIdsFromResultSetByConstraints($builder, $searchResults)
{
    $qualifiedKeyName    = $builder->model->getQualifiedKeyName(); // tableName.id
    $subQualifiedKeyName = 'sub.'.$builder->model->getKeyName(); // sub.id

    $sub = $this->getBuilder($builder->model)->whereIn(
        $qualifiedKeyName, $searchResults
    ); // sub query for left join

    $discardIds = $builder->model->newQuery()
        ->select($qualifiedKeyName)
        ->leftJoin(DB::raw('('.$sub->getQuery()->toSql().') as '.$builder->model->getConnection()->getTablePrefix().'sub'), $subQualifiedKeyName, '=', $qualifiedKeyName)
        ->addBinding($sub->getQuery()->getBindings(), 'join')
        ->whereIn($qualifiedKeyName, $searchResults)
        ->whereNull($subQualifiedKeyName)
        ->pluck($builder->model->getKeyName());

    // returns values of $results['ids'] that are not part of $discardIds
    return collect($searchResults)->diff($discardIds);
}

/**
 * Determine if the given model uses soft deletes.
 *
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @return bool
 */
protected function usesSoftDelete($model)
{
    return in_array(SoftDeletes::class, class_uses_recursive($model));
}

/**
 * Determine if soft delete is active and depending on state return the
 * appropriate builder.
 *
 * @param  Builder  $builder
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @return Builder
 */
private function handleSoftDeletes($builder, $model)
{
    // remove where statement for __soft_deleted when soft delete is not active
    // does not show soft deleted items when trait is attached to model and
    // config('scout.soft_delete') is false
    if (!$this->usesSoftDelete($model) || !config('scout.soft_delete', true)) {
        unset($this->builder->wheres['__soft_deleted']);
        return $builder;
    }

    /**
     * Use standard behaviour of Laravel Scout builder class to support soft deletes.
     *
     * When no __soft_deleted statement is given return all entries
     */
    if (!array_key_exists('__soft_deleted', $this->builder->wheres)) {
        return $builder->withTrashed();
    }

    /**
     * When __soft_deleted is 1 then return only soft deleted entries
     */
    if ($this->builder->wheres['__soft_deleted']) {
        $builder = $builder->onlyTrashed();
    }

    /**
     * Returns all undeleted entries, default behaviour
     */
    unset($this->builder->wheres['__soft_deleted']);
    return $builder;
}

/**
 * Apply where statements as constraints to the query builder.
 *
 * @param Builder $builder
 * @return \Illuminate\Support\Collection
 */
private function applyWheres($builder)
{
    // iterate over given where clauses
    return collect($this->builder->wheres)->map(function ($value, $key) {
        // for reduce function combine key and value into array
        return [$key, $value];
    })->reduce(function ($builder, $where) {
        // separate key, value again
        list($key, $value) = $where;
        return $builder->where($key, $value);
    }, $builder);
}

/**
 * Apply order by statements as constraints to the query builder.
 *
 * @param Builder $builder
 * @return \Illuminate\Support\Collection
 */
private function applyOrders($builder)
{
    //iterate over given orderBy clauses - should be only one
    return collect($this->builder->orders)->map(function ($value, $key) {
        // for reduce function combine key and value into array
        return [$value["column"], $value["direction"]];
    })->reduce(function ($builder, $orderBy) {
        // separate key, value again
        list($column, $direction) = $orderBy;
        return $builder->orderBy($column, $direction);
    }, $builder);
}

/**
 * Flush all of the model's records from the engine.
 *
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @return void
 */
public function flush($model)
{
    $indexName   = $model->searchableAs();
    $pathToIndex = $this->tnt->config['storage']."/{$indexName}.index";
    if (file_exists($pathToIndex)) {
        unlink($pathToIndex);
    }
}


/**
 * Create a search index.
 *
 * @param  string  $name
 * @param  array  $options
 * @return mixed
 *
 * @throws \Exception
 */
public function createIndex($name, array $options = [])
{
    throw new Exception('TNT indexes are created automatically upon adding objects.');
}

/**
 * Delete a search index.
 *
 * @param  string  $name
 * @return mixed
 */
public function deleteIndex($name)
{
    throw new Exception(sprintf('TNT indexes cannot reliably be removed. Please manually remove the file in %s/%s.index', config('scout.tntsearch.storage'), $name));
}

/**
 * Adds a filter
 *
 * @param  string
 * @param  callback
 * @return void
 */
public function addFilter($name, $callback)
{
    if (!is_callable($callback, true)) {
        throw new InvalidArgumentException(sprintf('Filter is an invalid callback: %s.', print_r($callback, true)));
    }
    $this->filters[$name][] = $callback;
}

/**
 * Returns an array of filters
 *
 * @param  string
 * @return array
 */
public function getFilters($name)
{
    return isset($this->filters[$name]) ? $this->filters[$name] : [];
}

/**
 * Returns a string on which a filter is applied
 *
 * @param  string
 * @param  string
 * @return string
 */
public function applyFilters($name, $result, $model)
{
    foreach ($this->getFilters($name) as $callback) {
        // prevent fatal errors, do your own warning or
        // exception here as you need it.
        if (!is_callable($callback)) {
            continue;
        }

        $result = call_user_func($callback, $result, $model);
    }
    return $result;
}

}

Source