[{"data":1,"prerenderedAt":871},["ShallowReactive",2],{"docs-cloud/frameworks/laravel-scout":3},{"id":4,"title":5,"body":6,"description":861,"extension":862,"meta":863,"navigation":201,"path":864,"seo":865,"seoDescription":866,"seoTitle":867,"sitemap":868,"stem":869,"__hash__":870},"docs/docs/cloud/frameworks/laravel-scout.md","Laravel Scout",{"type":7,"value":8,"toc":852},"minimark",[9,13,23,28,86,90,116,165,171,178,182,463,467,481,619,622,648,655,659,800,803,807,820,824,848],[10,11,5],"h1",{"id":12},"laravel-scout",[14,15,16,22],"p",{},[17,18,5],"a",{"href":19,"rel":20},"https://laravel.com/docs/scout",[21],"nofollow"," has a first-party Meilisearch\ndriver, so a CelerSearch instance works with it out of the box. Scout keeps\nyour search index in sync with your Eloquent models; CelerSearch runs the\nengine.",[24,25,27],"h2",{"id":26},"_1-install","1. Install",[29,30,35],"pre",{"className":31,"code":32,"language":33,"meta":34,"style":34},"language-bash shiki shiki-themes github-light github-dark","composer require laravel/scout\nphp artisan vendor:publish --provider=\"Laravel\\Scout\\ScoutServiceProvider\"\ncomposer require meilisearch/meilisearch-php http-interop/http-factory-guzzle\n","bash","",[36,37,38,54,73],"code",{"__ignoreMap":34},[39,40,43,47,51],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"sScJk","composer",[39,48,50],{"class":49},"sZZnC"," require",[39,52,53],{"class":49}," laravel/scout\n",[39,55,57,60,63,66,70],{"class":41,"line":56},2,[39,58,59],{"class":45},"php",[39,61,62],{"class":49}," artisan",[39,64,65],{"class":49}," vendor:publish",[39,67,69],{"class":68},"sj4cs"," --provider=",[39,71,72],{"class":49},"\"Laravel\\Scout\\ScoutServiceProvider\"\n",[39,74,76,78,80,83],{"class":41,"line":75},3,[39,77,46],{"class":45},[39,79,50],{"class":49},[39,81,82],{"class":49}," meilisearch/meilisearch-php",[39,84,85],{"class":49}," http-interop/http-factory-guzzle\n",[24,87,89],{"id":88},"_2-configure","2. Configure",[14,91,92,93,97,98,101,102,105,106,111,112,115],{},"Copy the ",[94,95,96],"strong",{},"Endpoint URL"," and ",[94,99,100],{},"API key"," from your instance's ",[94,103,104],{},"Connection\ndetails"," at ",[17,107,110],{"href":108,"rel":109},"https://app.celersearch.com",[21],"app.celersearch.com",", and set them\nin ",[36,113,114],{},".env",":",[29,117,119],{"className":31,"code":118,"filename":114,"language":33,"meta":34,"style":34},"SCOUT_DRIVER=meilisearch\nMEILISEARCH_HOST=https://your-endpoint-url\nMEILISEARCH_KEY=your-api-key\nSCOUT_QUEUE=true\n",[36,120,121,134,144,154],{"__ignoreMap":34},[39,122,123,127,131],{"class":41,"line":42},[39,124,126],{"class":125},"sVt8B","SCOUT_DRIVER",[39,128,130],{"class":129},"szBVR","=",[39,132,133],{"class":49},"meilisearch\n",[39,135,136,139,141],{"class":41,"line":56},[39,137,138],{"class":125},"MEILISEARCH_HOST",[39,140,130],{"class":129},[39,142,143],{"class":49},"https://your-endpoint-url\n",[39,145,146,149,151],{"class":41,"line":75},[39,147,148],{"class":125},"MEILISEARCH_KEY",[39,150,130],{"class":129},[39,152,153],{"class":49},"your-api-key\n",[39,155,157,160,162],{"class":41,"line":156},4,[39,158,159],{"class":125},"SCOUT_QUEUE",[39,161,130],{"class":129},[39,163,164],{"class":49},"true\n",[14,166,167,170],{},[36,168,169],{},"SCOUT_QUEUE=true"," sends index updates through your queue, so saving a model\nnever waits on a network call. It's optional, but recommended in production.",[172,173,175],"warning",{"title":174},"Server-side only",[14,176,177],{},"The API key has full access to your instance. Scout uses it from your\nserver, which is exactly where it belongs. Never pass it to your frontend.",[24,179,181],{"id":180},"_3-make-a-model-searchable","3. Make a model searchable",[29,183,187],{"className":184,"code":185,"filename":186,"language":59,"meta":34,"style":34},"language-php shiki shiki-themes github-light github-dark","\u003C?php\n\nnamespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Laravel\\Scout\\Searchable;\n\nclass Post extends Model\n{\n    use Searchable;\n\n    /**\n     * Get the indexable data array for the model.\n     *\n     * @return array\u003Cstring, mixed>\n     */\n    public function toSearchableArray(): array\n    {\n        return [\n            'id' => $this->id,\n            'title' => $this->title,\n            'body' => $this->body,\n            'category' => $this->category,\n            'created_at' => $this->created_at->timestamp,\n        ];\n    }\n}\n","app/Models/Post.php",[36,188,189,197,203,214,218,229,239,244,259,265,276,281,288,294,300,321,327,347,353,362,380,395,410,425,445,451,457],{"__ignoreMap":34},[39,190,191,194],{"class":41,"line":42},[39,192,193],{"class":129},"\u003C?",[39,195,196],{"class":68},"php\n",[39,198,199],{"class":41,"line":56},[39,200,202],{"emptyLinePlaceholder":201},true,"\n",[39,204,205,208,211],{"class":41,"line":75},[39,206,207],{"class":129},"namespace",[39,209,210],{"class":45}," App\\Models",[39,212,213],{"class":125},";\n",[39,215,216],{"class":41,"line":156},[39,217,202],{"emptyLinePlaceholder":201},[39,219,221,224,227],{"class":41,"line":220},5,[39,222,223],{"class":129},"use",[39,225,226],{"class":68}," Illuminate\\Database\\Eloquent\\Model",[39,228,213],{"class":125},[39,230,232,234,237],{"class":41,"line":231},6,[39,233,223],{"class":129},[39,235,236],{"class":68}," Laravel\\Scout\\Searchable",[39,238,213],{"class":125},[39,240,242],{"class":41,"line":241},7,[39,243,202],{"emptyLinePlaceholder":201},[39,245,247,250,253,256],{"class":41,"line":246},8,[39,248,249],{"class":129},"class",[39,251,252],{"class":45}," Post",[39,254,255],{"class":129}," extends",[39,257,258],{"class":45}," Model\n",[39,260,262],{"class":41,"line":261},9,[39,263,264],{"class":125},"{\n",[39,266,268,271,274],{"class":41,"line":267},10,[39,269,270],{"class":129},"    use",[39,272,273],{"class":68}," Searchable",[39,275,213],{"class":125},[39,277,279],{"class":41,"line":278},11,[39,280,202],{"emptyLinePlaceholder":201},[39,282,284],{"class":41,"line":283},12,[39,285,287],{"class":286},"sJ8bj","    /**\n",[39,289,291],{"class":41,"line":290},13,[39,292,293],{"class":286},"     * Get the indexable data array for the model.\n",[39,295,297],{"class":41,"line":296},14,[39,298,299],{"class":286},"     *\n",[39,301,303,306,309,312,315,318],{"class":41,"line":302},15,[39,304,305],{"class":286},"     * ",[39,307,308],{"class":129},"@return",[39,310,311],{"class":129}," array",[39,313,314],{"class":286},"\u003C",[39,316,317],{"class":129},"string",[39,319,320],{"class":286},", mixed>\n",[39,322,324],{"class":41,"line":323},16,[39,325,326],{"class":286},"     */\n",[39,328,330,333,336,339,342,344],{"class":41,"line":329},17,[39,331,332],{"class":129},"    public",[39,334,335],{"class":129}," function",[39,337,338],{"class":45}," toSearchableArray",[39,340,341],{"class":125},"()",[39,343,115],{"class":129},[39,345,346],{"class":129}," array\n",[39,348,350],{"class":41,"line":349},18,[39,351,352],{"class":125},"    {\n",[39,354,356,359],{"class":41,"line":355},19,[39,357,358],{"class":129},"        return",[39,360,361],{"class":125}," [\n",[39,363,365,368,371,374,377],{"class":41,"line":364},20,[39,366,367],{"class":49},"            'id'",[39,369,370],{"class":129}," =>",[39,372,373],{"class":68}," $this",[39,375,376],{"class":129},"->",[39,378,379],{"class":125},"id,\n",[39,381,383,386,388,390,392],{"class":41,"line":382},21,[39,384,385],{"class":49},"            'title'",[39,387,370],{"class":129},[39,389,373],{"class":68},[39,391,376],{"class":129},[39,393,394],{"class":125},"title,\n",[39,396,398,401,403,405,407],{"class":41,"line":397},22,[39,399,400],{"class":49},"            'body'",[39,402,370],{"class":129},[39,404,373],{"class":68},[39,406,376],{"class":129},[39,408,409],{"class":125},"body,\n",[39,411,413,416,418,420,422],{"class":41,"line":412},23,[39,414,415],{"class":49},"            'category'",[39,417,370],{"class":129},[39,419,373],{"class":68},[39,421,376],{"class":129},[39,423,424],{"class":125},"category,\n",[39,426,428,431,433,435,437,440,442],{"class":41,"line":427},24,[39,429,430],{"class":49},"            'created_at'",[39,432,370],{"class":129},[39,434,373],{"class":68},[39,436,376],{"class":129},[39,438,439],{"class":125},"created_at",[39,441,376],{"class":129},[39,443,444],{"class":125},"timestamp,\n",[39,446,448],{"class":41,"line":447},25,[39,449,450],{"class":125},"        ];\n",[39,452,454],{"class":41,"line":453},26,[39,455,456],{"class":125},"    }\n",[39,458,460],{"class":41,"line":459},27,[39,461,462],{"class":125},"}\n",[24,464,466],{"id":465},"_4-configure-index-settings","4. Configure index settings",[14,468,469,470,473,474,477,478,115],{},"Attributes you filter on with ",[36,471,472],{},"where"," must be filterable, and attributes you\nsort on with ",[36,475,476],{},"orderBy"," must be sortable. Declare them in ",[36,479,480],{},"config/scout.php",[29,482,484],{"className":184,"code":483,"filename":480,"language":59,"meta":34,"style":34},"use App\\Models\\Post;\n\n'meilisearch' => [\n    'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),\n    'key' => env('MEILISEARCH_KEY', null),\n    'index-settings' => [\n        Post::class => [\n            'filterableAttributes' => ['category'],\n            'sortableAttributes' => ['created_at'],\n        ],\n    ],\n],\n",[36,485,486,495,499,508,533,554,563,575,591,605,610,615],{"__ignoreMap":34},[39,487,488,490,493],{"class":41,"line":42},[39,489,223],{"class":129},[39,491,492],{"class":68}," App\\Models\\Post",[39,494,213],{"class":125},[39,496,497],{"class":41,"line":56},[39,498,202],{"emptyLinePlaceholder":201},[39,500,501,504,506],{"class":41,"line":75},[39,502,503],{"class":49},"'meilisearch'",[39,505,370],{"class":129},[39,507,361],{"class":125},[39,509,510,513,515,518,521,524,527,530],{"class":41,"line":156},[39,511,512],{"class":49},"    'host'",[39,514,370],{"class":129},[39,516,517],{"class":45}," env",[39,519,520],{"class":125},"(",[39,522,523],{"class":49},"'MEILISEARCH_HOST'",[39,525,526],{"class":125},", ",[39,528,529],{"class":49},"'http://localhost:7700'",[39,531,532],{"class":125},"),\n",[39,534,535,538,540,542,544,547,549,552],{"class":41,"line":220},[39,536,537],{"class":49},"    'key'",[39,539,370],{"class":129},[39,541,517],{"class":45},[39,543,520],{"class":125},[39,545,546],{"class":49},"'MEILISEARCH_KEY'",[39,548,526],{"class":125},[39,550,551],{"class":68},"null",[39,553,532],{"class":125},[39,555,556,559,561],{"class":41,"line":231},[39,557,558],{"class":49},"    'index-settings'",[39,560,370],{"class":129},[39,562,361],{"class":125},[39,564,565,568,571,573],{"class":41,"line":241},[39,566,567],{"class":68},"        Post",[39,569,570],{"class":129},"::class",[39,572,370],{"class":129},[39,574,361],{"class":125},[39,576,577,580,582,585,588],{"class":41,"line":246},[39,578,579],{"class":49},"            'filterableAttributes'",[39,581,370],{"class":129},[39,583,584],{"class":125}," [",[39,586,587],{"class":49},"'category'",[39,589,590],{"class":125},"],\n",[39,592,593,596,598,600,603],{"class":41,"line":261},[39,594,595],{"class":49},"            'sortableAttributes'",[39,597,370],{"class":129},[39,599,584],{"class":125},[39,601,602],{"class":49},"'created_at'",[39,604,590],{"class":125},[39,606,607],{"class":41,"line":267},[39,608,609],{"class":125},"        ],\n",[39,611,612],{"class":41,"line":278},[39,613,614],{"class":125},"    ],\n",[39,616,617],{"class":41,"line":283},[39,618,590],{"class":125},[14,620,621],{},"Push the settings to your instance, then import your existing records:",[29,623,625],{"className":31,"code":624,"language":33,"meta":34,"style":34},"php artisan scout:sync-index-settings\nphp artisan scout:import \"App\\Models\\Post\"\n",[36,626,627,636],{"__ignoreMap":34},[39,628,629,631,633],{"class":41,"line":42},[39,630,59],{"class":45},[39,632,62],{"class":49},[39,634,635],{"class":49}," scout:sync-index-settings\n",[39,637,638,640,642,645],{"class":41,"line":56},[39,639,59],{"class":45},[39,641,62],{"class":49},[39,643,644],{"class":49}," scout:import",[39,646,647],{"class":49}," \"App\\Models\\Post\"\n",[14,649,650,651,654],{},"Add ",[36,652,653],{},"scout:sync-index-settings"," to your deploy process so settings changes\nreach the instance.",[24,656,658],{"id":657},"_5-search","5. Search",[29,660,662],{"className":184,"code":661,"language":59,"meta":34,"style":34},"use App\\Models\\Post;\n\n// Typo-tolerant full-text search\n$posts = Post::search('larvel scuot')->get();\n\n// Filter, sort and paginate\n$posts = Post::search($request->input('query'))\n    ->where('category', 'tutorials')\n    ->orderBy('created_at', 'desc')\n    ->paginate(15);\n",[36,663,664,672,676,681,712,716,721,749,768,785],{"__ignoreMap":34},[39,665,666,668,670],{"class":41,"line":42},[39,667,223],{"class":129},[39,669,492],{"class":68},[39,671,213],{"class":125},[39,673,674],{"class":41,"line":56},[39,675,202],{"emptyLinePlaceholder":201},[39,677,678],{"class":41,"line":75},[39,679,680],{"class":286},"// Typo-tolerant full-text search\n",[39,682,683,686,688,690,693,696,698,701,704,706,709],{"class":41,"line":156},[39,684,685],{"class":125},"$posts ",[39,687,130],{"class":129},[39,689,252],{"class":68},[39,691,692],{"class":129},"::",[39,694,695],{"class":45},"search",[39,697,520],{"class":125},[39,699,700],{"class":49},"'larvel scuot'",[39,702,703],{"class":125},")",[39,705,376],{"class":129},[39,707,708],{"class":45},"get",[39,710,711],{"class":125},"();\n",[39,713,714],{"class":41,"line":220},[39,715,202],{"emptyLinePlaceholder":201},[39,717,718],{"class":41,"line":231},[39,719,720],{"class":286},"// Filter, sort and paginate\n",[39,722,723,725,727,729,731,733,736,738,741,743,746],{"class":41,"line":241},[39,724,685],{"class":125},[39,726,130],{"class":129},[39,728,252],{"class":68},[39,730,692],{"class":129},[39,732,695],{"class":45},[39,734,735],{"class":125},"($request",[39,737,376],{"class":129},[39,739,740],{"class":45},"input",[39,742,520],{"class":125},[39,744,745],{"class":49},"'query'",[39,747,748],{"class":125},"))\n",[39,750,751,754,756,758,760,762,765],{"class":41,"line":246},[39,752,753],{"class":129},"    ->",[39,755,472],{"class":45},[39,757,520],{"class":125},[39,759,587],{"class":49},[39,761,526],{"class":125},[39,763,764],{"class":49},"'tutorials'",[39,766,767],{"class":125},")\n",[39,769,770,772,774,776,778,780,783],{"class":41,"line":261},[39,771,753],{"class":129},[39,773,476],{"class":45},[39,775,520],{"class":125},[39,777,602],{"class":49},[39,779,526],{"class":125},[39,781,782],{"class":49},"'desc'",[39,784,767],{"class":125},[39,786,787,789,792,794,797],{"class":41,"line":267},[39,788,753],{"class":129},[39,790,791],{"class":45},"paginate",[39,793,520],{"class":125},[39,795,796],{"class":68},"15",[39,798,799],{"class":125},");\n",[14,801,802],{},"From here on, Scout indexes models as they're created, updated and deleted.",[24,804,806],{"id":805},"plans-and-limits","Plans and limits",[14,808,809,810,814,815,819],{},"Every record Scout imports counts as one document toward your plan's\n",[17,811,813],{"href":812},"/docs/cloud/plans","document limit",". Searches are always unlimited. If you\nreach the limit, new writes are refused until you delete documents or move to\na larger plan. See ",[17,816,818],{"href":817},"/docs/cloud/connect-any-app#when-you-reach-the-document-limit","Connect Any App",".",[24,821,823],{"id":822},"next-steps","Next steps",[825,826,827,834,841],"ul",{},[828,829,830,833],"li",{},[17,831,818],{"href":832},"/docs/cloud/connect-any-app",": connection details, platform responses and browser search",[828,835,836,840],{},[17,837,839],{"href":838},"/docs/cloud/migrate","Migrate to CelerSearch",": move an existing index from another Meilisearch",[828,842,843,847],{},[17,844,846],{"href":845},"/pricing","Pricing",": plans by document count",[849,850,851],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":34,"searchDepth":56,"depth":56,"links":853},[854,855,856,857,858,859,860],{"id":26,"depth":56,"text":27},{"id":88,"depth":56,"text":89},{"id":180,"depth":56,"text":181},{"id":465,"depth":56,"text":466},{"id":657,"depth":56,"text":658},{"id":805,"depth":56,"text":806},{"id":822,"depth":56,"text":823},"Use Laravel Scout's Meilisearch driver with a managed CelerSearch instance. Set two environment variables, import your models, and search Eloquent with typo tolerance.","md",{},"/docs/cloud/frameworks/laravel-scout",{"title":5,"description":861},"Connect Laravel Scout's Meilisearch driver to a managed CelerSearch instance. Configure .env, sync index settings, import models and search Eloquent.","Laravel Scout with Managed Meilisearch",{"loc":864},"docs/cloud/frameworks/laravel-scout","sWTWjftq6GS1bKtlI-7PG_0sFfOLJ8eXS__tAcb8_Jk",1792316274551]