php 61 lines · 8 steps

Making an Eloquent model searchable with Scout in Laravel

How Laravel Scout indexes an Article model and hands back full-text search results in relevance order.

Explained by highlit
1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Builder;
6use Illuminate\Database\Eloquent\Model;
7use Illuminate\Database\Eloquent\Relations\BelongsTo;
8use Laravel\Scout\Searchable;
9 
10class Article extends Model
11{
12 use Searchable;
13 
14 protected $fillable = ['title', 'body', 'status', 'author_id', 'published_at'];
15 
16 protected $casts = [
17 'published_at' => 'datetime',
18 ];
19 
20 public function author(): BelongsTo
21 {
22 return $this->belongsTo(User::class, 'author_id');
23 }
24 
25 public function searchableAs(): string
26 {
27 return 'articles_index';
28 }
29 
30 public function toSearchableArray(): array
31 {
32 return [
33 'id' => (int) $this->id,
34 'title' => $this->title,
35 'body' => $this->body,
36 'author' => $this->author?->name,
37 'published_at' => $this->published_at?->timestamp,
38 ];
39 }
40 
41 public function shouldBeSearchable(): bool
42 {
43 return $this->status === 'published';
44 }
45 
46 public function makeAllSearchableUsing(Builder $query): Builder
47 {
48 return $query->with('author');
49 }
50 
51 public function scopeSearchPublished(Builder $query, string $term): Builder
52 {
53 $ids = static::search($term)
54 ->where('published_at', '<=', now()->timestamp)
55 ->take(50)
56 ->keys();
57 
58 return $query->whereIn('id', $ids)
59 ->orderByRaw('FIELD(id, ' . $ids->implode(',') . ')');
60 }
61}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Scout lets you customize exactly what gets indexed and when, so the search engine only ever sees the shape and subset of data you want.
  2. 2Eager-loading during bulk indexing avoids N+1 queries when your searchable payload pulls in related models.
  3. 3Search engines return IDs, not ordered rows, so you must re-impose relevance order yourself when hydrating from the database.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Making an Eloquent model searchable with Scout in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code