Managed to load relationship on my previous project using Scout with Meilisearch driver. You have to load relations inside query builder closure. Btw, Meilisearch is great if you don't want to setup the massive Elasticsearch or pay for cloud solutions (Algolia/ElasticCloud). $locations = Model::search($query)->query(function (Builder $builder) use $uniqueValue { $builder->where('field', $uniqueValue)->with('services'); })->paginate(15); the $uniqueValue is an outside variable to 'fixed' filter the search throughout the same search session. (e.g: userId). No need to use it if you don't have to.
i found an error like this Attribute `user_id` is not filterable. This index does not have configured filterable attributes. 1:8 user_id=1 can u help me to solve it
At least with Algolia you can define relationships in your model Here's an example implementation where you're searching all of one model and then a relationship (categories) public function toSearchableArray() { $array = $this->toArray(); $array = $this->transform($array); $array['categories'] = $this->categories->map(function ($data) { return $data['name']; })->toArray(); return $array; }
A search that doesn’t work with eloquent relationships? Complete dealbreaker for me. It’s easy enough to just write a custom search yourself. This video saved me some time, as I was about to use Scout. Now I know not to waste my time on it. Seems like others in the comments have workarounds, but it’s easier to just code the search myself.
I guess Algolia or Elasticsearch (or whatever fulltext search engine) would do the trick with relations. The only downside is that you will have to perform indexing of the DB to that search engine. Also, the performance - not all servers are capable of running Docker container with Elasticsearch in it, since it's quite heavy (not sure about Algolia though). But yeah - I am considering to introduce ES to my project, since customer wants to search users by partially name and surname (like "Jo Sm" if it is John Smith) and building mega-queries in the controller (or in repository in my case) is not the best idea ever.
I have been wondering the overall purpose of Scout. I have been using local scopes for "searchable" database queries. I find that I have total control over how the query is behaves. Also works well with relationships. The controller stays the same but only one more function in the model.
Yes you can do it that way. Scout was mostly built to use external tools that were built specifically for text search with a lot more features around it, not just queries, and also those external tools may run faster than your local database, ironically.
Search and analytics databases such as Elasticsearch, Algolia, Meilisearch, Lucene, etc - are databases that were designed for the main purpose of indexing massive and mostly unstructured data. You can throw anything to it without having to worry about structure like SQL does, and they still do an awesome job on text search. Plus, having your main ACID database handling search will potentially bottleneck it at some point, e.g: Postgres will have increasing write speed as you add indexes. If you have/foresee small amount of data then it doesn't matter much.
Haven't tried it yet but skimming through the docs, it seems you could use 'makeAllSearchableUsing()' to do your eager loading on the models , and then adding them to search in 'toSearchableArray()' but I could be wrong, see 'Modifying The Import Query' in the docs, anyways thanks for the video
Hi, Thanks for this video, I know search is very useful I always use Algolia. I just want to know one thing, is it possible if user spell wrong but need to show correct result? EG: If user search 'Calofornua' can we show results to actual word 'California' ?
Sorry I'm a little bit late, but a possible solution for searching in relations, could it be to add on the searcheable array and index called 'country' => this->country->name or wouldn't work? maybe it will generate a N + 1 issue there right?
Firstly I'm sorry for my irrelevant question. Could you please explain what is the difference between make:channel and make:event? Are those the same things with just different directories and namespaces? Or their usages and functionality are different? Thenk you.
Can't you add relationship values in the searchable array definition in the model. This is kind of how algolia does it. If that works,ot sure however this would impact the performance, e.g. n±1 issues.Just thinking out loud here,didn't test anything
Not related to the topic but how to fix that flickering when you click to another page or refresh the page? I tried adding x-cloak but its not working.
@@LaravelDaily I tried it on newly installed larastarter with tailwind components, it did fix the dropdown for profile and logout but I don't know where to put it to fix the whole page, I tried putting it at the app and individual components but it didn't work.
I use my own simple local scope: on top you need to have search property in this format: $search = [ 'name', 'country' => [ 'name' ] ]; it works pretty well for me. public function scopeSearch($query, $string = NULL) { if ($string == null) return $query; $words = []; if (stripos($string, ' ') !== false) { $words = explode(' ', $string); } $q = $query; if (count($words) > 0) { foreach ($words as $item) { foreach ($this->search as $key => $column) { if (is_array($column) && count($column) > 0) { $q->orWhereHas($key, function ($query) use ($column, $item) { $query->where(function ($sub_query) use ($column, $item) { foreach ($column as $sub_column) { $sub_query->orWhere($sub_column, 'LIKE', "%{$item}%"); } }); }); } else $q->orWhere($column, 'LIKE', "%{$item}%"); } } return $q; } else { $q->where(function ($qq) use ($string) { foreach ($this->search as $key => $column) { if (is_array($column) && count($column) > 0) { $qq->orWhereHas($key, function ($query) use ($column, $string) { $query->where(function ($sub_query) use ($column, $string) { foreach ($column as $sub_column) { $sub_query->orWhere($sub_column, 'LIKE', "%{$string}%"); } }); }); } else $qq->orWhere($column, 'LIKE', "%{$string}%"); } }); return $q; } }
I'd used that in one of my previous projects. I don’t know whether it works now or not. If it works, thank me in your next video. Else if doesn’t work, then I'm sorry.
I like this package because it returns some results even when the user makes some typo, like, searching for 'fod' will also return 'food' from tnt. This is not possible using the "like" in mysql
Managed to load relationship on my previous project using Scout with Meilisearch driver. You have to load relations inside query builder closure. Btw, Meilisearch is great if you don't want to setup the massive Elasticsearch or pay for cloud solutions (Algolia/ElasticCloud).
$locations = Model::search($query)->query(function (Builder $builder) use $uniqueValue {
$builder->where('field', $uniqueValue)->with('services');
})->paginate(15);
the $uniqueValue is an outside variable to 'fixed' filter the search throughout the same search session. (e.g: userId). No need to use it if you don't have to.
Dope!
i found an error like this Attribute `user_id` is not filterable. This index does not have configured filterable attributes. 1:8 user_id=1 can u help me to solve it
At least with Algolia you can define relationships in your model
Here's an example implementation where you're searching all of one model and then a relationship (categories)
public function toSearchableArray()
{
$array = $this->toArray();
$array = $this->transform($array);
$array['categories'] = $this->categories->map(function ($data) {
return $data['name'];
})->toArray();
return $array;
}
A search that doesn’t work with eloquent relationships? Complete dealbreaker for me. It’s easy enough to just write a custom search yourself. This video saved me some time, as I was about to use Scout. Now I know not to waste my time on it. Seems like others in the comments have workarounds, but it’s easier to just code the search myself.
I guess Algolia or Elasticsearch (or whatever fulltext search engine) would do the trick with relations. The only downside is that you will have to perform indexing of the DB to that search engine. Also, the performance - not all servers are capable of running Docker container with Elasticsearch in it, since it's quite heavy (not sure about Algolia though). But yeah - I am considering to introduce ES to my project, since customer wants to search users by partially name and surname (like "Jo Sm" if it is John Smith) and building mega-queries in the controller (or in repository in my case) is not the best idea ever.
User::search(request('search'))->query(function($query) {
$query->with('relation');
})->paginate(10);
Yes this works well
Funciona voy a seguir probándolo con otras formas
Works like a charm. 😅
I have been wondering the overall purpose of Scout. I have been using local scopes for "searchable" database queries. I find that I have total control over how the query is behaves. Also works well with relationships. The controller stays the same but only one more function in the model.
Yes you can do it that way. Scout was mostly built to use external tools that were built specifically for text search with a lot more features around it, not just queries, and also those external tools may run faster than your local database, ironically.
Search and analytics databases such as Elasticsearch, Algolia, Meilisearch, Lucene, etc - are databases that were designed for the main purpose of indexing massive and mostly unstructured data.
You can throw anything to it without having to worry about structure like SQL does, and they still do an awesome job on text search.
Plus, having your main ACID database handling search will potentially bottleneck it at some point, e.g: Postgres will have increasing write speed as you add indexes.
If you have/foresee small amount of data then it doesn't matter much.
Haven't tried it yet but skimming through the docs, it seems you could use 'makeAllSearchableUsing()' to do your eager loading on the models , and then adding them to search in 'toSearchableArray()' but I could be wrong, see 'Modifying The Import Query' in the docs, anyways thanks for the video
It's about time, thank you 🙌
so glad about this
Hi, Thanks for this video, I know search is very useful I always use Algolia. I just want to know one thing, is it possible if user spell wrong but need to show correct result? EG: If user search 'Calofornua' can we show results to actual word 'California' ?
Hello, sir. For the index.blade, no need to add anything?
I have a question, is it possible to add LOWER() function to index in sql query when we use scout?
Sorry I'm a little bit late, but a possible solution for searching in relations, could it be to add on the searcheable array and index called 'country' => this->country->name or wouldn't work? maybe it will generate a N + 1 issue there right?
Thanks. It looks easy but what do You think the performance?
The performance is the same as you would use Eloquent, nothing different.
Bro, you can just do pluck IDs on search and where in in the model alongside with eager loading
Can you make a video about scout and elasticsearch? With relations search. On Algolia its easy but i want to see how you doing it in elasticsearch
I don't use elasticsearch myself, so can't make a video about it.
@@LaravelDaily than what are you using? for full text search
Algolia
@@LaravelDaily Algolia is good but i think its little bit expensive for little companies)
Seems like a PR to search on eager loaded relationships should have no problems in getting approved?
There's only one way to find out :)
rarely see Povilas using Larastater instead of QuickAdminPanel xD
I use both, depending on the need, and mood :)
I think that Laravel Scout is like spatie/laravel-searchable
For database driver, yes. But if you use external drivers like Algolia, Scout is much more powerful
Firstly I'm sorry for my irrelevant question. Could you please explain what is the difference between make:channel and make:event? Are those the same things with just different directories and namespaces? Or their usages and functionality are different? Thenk you.
It's different. Event can be broadcasted via multiple channels.
Please make a video on integrating google shopping feed api on Laravel. Really Needed that
I haven't worked with it
@@LaravelDaily Can we do easy multi tenancy tutorials/ guide?
Search the channel, please: ua-cam.com/users/LaravelDailysearch?query=tenancy
Can't you add relationship values in the searchable array definition in the model. This is kind of how algolia does it. If that works,ot sure however this would impact the performance, e.g. n±1 issues.Just thinking out loud here,didn't test anything
Yeah I also didn't test. Official docs don't say anything about relationships so I guess officially it's not supported
what syntax is this *key:'search'* and *var_name:'users'* as an argument? in what version it was introduced?
PHP 8 named parameters. Also, phpstorm auto suggests this to me
@@LaravelDaily Thank you for the reply. Could you please talk about DTO in Laravel?
Thank you very much sir
There is support for morphologies in Russian, English etc ?
Probably not, by default
what is the code in the search component?
what about if you want to look for username and users that are active(as a boolean field)?
You add that as a where stateme probably
maybe something like this?
public function shouldBeSearchable(): bool
{
return $this->is_active;
}
Can you kindly suggest me a complete working tutorial to implement elastic search in laravel 9?
I don't have anything about it myself, sorry, google it
@@LaravelDaily thanks anyways
If anyone else looking for something try doing it with elasticsearch package
Not related to the topic but how to fix that flickering when you click to another page or refresh the page? I tried adding x-cloak but its not working.
X-cloak should be the solution, not sure why it's not working for you. It should be x-cloak and then adding css style for it.
@@LaravelDaily I tried it on newly installed larastarter with tailwind components, it did fix the dropdown for profile and logout but I don't know where to put it to fix the whole page, I tried putting it at the app and individual components but it didn't work.
I came here just to see how scout works with relationships... 🤕
Is it possible to use this in Laravel 8 too?
No, only 9
in the next video search in relation table.
you are using Algolia not Elastics, right? I don't see anything relative in elastics in your code of laravel
It's the database driver, internal Laravel with DB locally, no algolia or elastic
Merci beaucoup interessant mais je ne comprend pas l'anglais. Songez a traduire le son de vos tutoriel en francais aussi
I use my own simple local scope:
on top you need to have search property in this format: $search = [ 'name', 'country' => [ 'name' ] ]; it works pretty well for me.
public function scopeSearch($query, $string = NULL)
{
if ($string == null) return $query;
$words = [];
if (stripos($string, ' ') !== false) {
$words = explode(' ', $string);
}
$q = $query;
if (count($words) > 0) {
foreach ($words as $item) {
foreach ($this->search as $key => $column) {
if (is_array($column) && count($column) > 0) {
$q->orWhereHas($key, function ($query) use ($column, $item) {
$query->where(function ($sub_query) use ($column, $item) {
foreach ($column as $sub_column) {
$sub_query->orWhere($sub_column, 'LIKE', "%{$item}%");
}
});
});
} else $q->orWhere($column, 'LIKE', "%{$item}%");
}
}
return $q;
} else {
$q->where(function ($qq) use ($string) {
foreach ($this->search as $key => $column) {
if (is_array($column) && count($column) > 0) {
$qq->orWhereHas($key, function ($query) use ($column, $string) {
$query->where(function ($sub_query) use ($column, $string) {
foreach ($column as $sub_column) {
$sub_query->orWhere($sub_column, 'LIKE', "%{$string}%");
}
});
});
} else $qq->orWhere($column, 'LIKE', "%{$string}%");
}
});
return $q;
}
}
Are you in Lithuania? Get out of there!
Yes it's getting "hotter" in here, but ok for now. Thanks for the advice!
User::search('term')->query(fn ($query) => $query->with('country'))->paginate(10);
I'd used that in one of my previous projects. I don’t know whether it works now or not.
If it works, thank me in your next video. Else if doesn’t work, then I'm sorry.
@@bdsumon4u Doesn't seem to.
this code is not working
Why not simply using MySQL fulltext search?
Did you read the docs? (#[SearchUsingFullText(['bio'])])
@@fahnleindieselschweif5022 my fault. thanks.
I am using teamtnt/laravel-scout-tntsearch-driver but I would really like to use a standard laravel function.
I like this package because it returns some results even when the user makes some typo, like, searching for 'fod' will also return 'food' from tnt. This is not possible using the "like" in mysql