$files->search() parameters and searching with additional fields

Goal: I’m trying to build a website search, that allows to filter by downloads. Basically, when I decide to filter for downloads, It should show me pages that have files (from a specific file blueprint called downloads) that match the search query, based on the file name and probably other fields defined on the file blueprint.


When I just search for pages, I would use $pages->search() and can define any additional parameters, for example score and fields, to give weight to certain fields.

Based on the documentation and the fact that files also build on top of Collection, I assume $files->search() parameters are the same, even though the documentation only describes it as an array, without further explanation.

Now, what is not clear to me: Whether $files->search() includes any information from the file blueprint or if it is a raw file search based on filename only.

Because I tried to do something like that:

$fileResults = $site->index()->files()->search($query, [
    'fields' => ['name', 'friendly_name'],
    'score' => ['friendly_name' => 64, 'name' => 32]
]);

Where friendly_name is a text field on the file blueprint, allowing content editors to set a title for the download as shown to the users on the website.

It doesn’t look like these kinds of parameters work on the file search. It does emit zero results at anytime.

The question then is: How do I correctly search all pages for files matching the query? Because $site->index()->search($query, 'downloads'); (limiting it to the file upload fields) does not work either. Also, this doesn’t allow me to extend which fields of the downloads should be included.

instead of the search you could just do a filerBy on the “all files collection”

$result = $site->index()->files()->filterBy(function($file) use ($query) {
  return $file->name() === $query || Str::contains($file->friendly_name()->value(), $query);
});

but given how many files and pages you have you can expect that to take increasingly more time. you could add some kind of caching by creating a search index cache. on file create or update hook write name and friendly_name to a single big array. with file id as key. that array will hold all search data of all files no matter where they are. searching that should be much faster than using the collection.

1 Like

Internally, search doesn’t do anything else but filter, so if you want to include the filename in the search, @bnomei’s suggestion is the way to go. Because the search() method only searches in the content, not filename.

1 Like

Alright, thanks @bnomei, @texnixe.

I kind of thought of that solution, but assumed search() might do some additional clever things that might be better for performance.

So, filterBy is fine then.

Well, it does the scoring on top, but apart from that, nothing performance wise. The cache is definitely a good idea with many files.