yabhq / laravel-scout-mysql-driver Goto Github PK
View Code? Open in Web Editor NEWLaravel Scout MySQL Driver
License: MIT License
Laravel Scout MySQL Driver
License: MIT License
I'm not sure if this would be more a Scout limitation or the driver here.
I have a model that contains a table for a phone number. Unfortunately I'm working with an existing database where they did not standardize these fields, as such phone numbers can contain dashes, spaces, parenthesis, etc.
So as a result I'm using a Accessor on this:
public function getPhoneAttribute($value)
{
return preg_replace("/[^A-Za-z0-9]/", "", $value);
}
However, when utilizing search it seems to ignore this and still looks for the original value with dashes, etc.
I have a general problem when searching with this package. For example when I search for Barbara
- when the search term is Ba
, the Barbara's are found, with Barb
I get no results. Even with Barbara
as the search term, nothing is found.
I'm running:
... and use the default config:
'mysql' => [
'mode' => 'NATURAL_LANGUAGE',
'model_directories' => [app_path() . '/Models'],
'min_search_length' => 0,
'min_fulltext_search_length' => 4,
'min_fulltext_search_fallback' => 'LIKE',
'query_expansion' => false
]
5.5 will hit fairly soon. Any plans on adding it to the semver in the composer.json
?
It seems to be working perfectly fine under 5.5 already, but my tests are probably inadequate.
If, like me, you move your models into a Models
namespace, the package fails to detect the namespace change.
Hello,
Thanks for your great package. I installed it for laravel 5.4
and it worked fine, but when i tried to install in laravel 5.5
, it won't installed.
please support for laravel 5.5
I have a table prefix set in config/database.php: 'prefix' => 'pref_', but the drivers searches while using the table name without the prefix.
Title is self explanatory, but yeah, let's say I'm making a search in an artist table, looking for Lady Gaga
.
Artist::search('gag')->get()
returns nothing.
Artist::search('%gag%')->get()
returns the row with Lady Gaga
in it.
My understanding from your doc was that it was made automatically, but it's not?
Hello there, we are facing problem while updating to laravel 5.5 due to this package. It is updated at github but not at packagist.org.
composer.json
"laravel/framework": "5.4.*",
"laravel/scout": "^3.0",
"damiantw/laravel-scout-mysql-driver": "^1.0"
Problem:
damiantw/laravel-scout-mysql-driver v1.0.7
requires laravel/framework 5.3.*
and laravel/scout ^2.0
can't do a search in Persian or Arabic
SQLSTATE[HY000]: General error: 1271 Illegal mix of collations for operation 'like' (SQL: select count(*) as aggregate from
items where (
idLIKE %سلام% OR
titleLIKE %سلام% OR
introLIKE %سلام% OR
descriptionLIKE %سلام% OR
thumbnailLIKE %سلام% OR
imagesLIKE %سلام% OR
priceLIKE %سلام% OR
statusLIKE %سلام% OR
user_idLIKE %سلام% OR
created_atLIKE %سلام% OR
updated_atLIKE %سلام% OR
deleted_atLIKE %سلام% OR
slugLIKE %سلام%) and
items.
deleted_at is null)
Hi there, I was using elasticsearch driver and I had no trouble indexing relationships
like this:
public function toSearchableArray()
{
$array = $this->toArray();
// Customize array...
$array = remove_from_array($array, $this->appends);
$extra_data = [];
if ($this->company) {
$extra_data['company_name'] = $this->company->name;
}
return array_merge($array, $extra_data);
}
But have no idea how to achieve the same with mysql driver
I have a lot of text fields - is it possible to specify which fields to index? Doing the import as is results in a nasty error.
Is it possible to search within multiple tables/models and get the result in a singel collection? I can't find something about it in the manual.
Hi,
is it posible to limit of results by relevance?
Something like:
SELECT *, MATCH(name,title,text) AGAINST('some text' IN BOOLEAN MODE) AS relevance
FROM `search_articles`
WHERE MATCH(name,title,text) AGAINST('some text' IN BOOLEAN MODE)
HAVING relevance > 10
ORDER BY relevance DESC
Thanks
I have a model Post
use GlobalScope
protected static function boot()
{
parent::boot();
static::addGlobalScope('status', function(Builder $builder) {
$builder->where('status', '=', 1);
});
}
And use laravel-scout-mysql-driver
for search q=dfds
It occur QueryException
select count(*) as aggregate from `posts` where (`content` LIKE :_search0) and `posts`.`deleted_at` is null and `status` = %dfds%)
I have an old table with lot's of fulltext capable fields and cannot remove them. When I am trying to add the indexes I get the response that a maximum of 16 fields are allowed while I have 17. Only three of them contain real data to search on.
It would be nice to have a possibility to limit the fields to create an fulltext search index on and eventually to search in.
A nice way to do this is by adding a $searchable array to the model like this:
use Laravel\Scout\Searchable;
class Product extends Model
{
use Searchable;
protected $searchable = [
'menu',
'title',
'text'
];
...
}
hi.
I want to search some part of text. for example in the "applegood" I want to search "ppleg" return result.
but in NATURAL_LANGUAGE mode it returns no result; so in BOOLEAN mode i use * ppleg * and no result returned. but in "apple*" results returned.
so can i have search like this in NATURAL_LANGUAGE? and if not how can use "*" operator in first of query?
During the development everything was fine. But after deployment, I'm getting this error:
'Yab\MySQLScout\Engines\Modes\LIke' not found
First, I got this error on database migrations. Then i commented use Searchable
lines on my models and successfully migrated. After migration I've remove the comment and indexed my models. But when I'm trying to search a query, I'm still getting this error.
Here is my scout configuration
'mysql' => [ 'mode' => 'NATURAL_LANGUAGE', 'model_directories' => [app_path()], 'min_search_length' => 1, 'min_fulltext_search_length' => 1, 'min_fulltext_search_fallback' => 'LIKE', 'query_expansion' => false ],
My deadline is in 24 hours. So, any help will be appreciated.
Using version ^1.0 for damiantw/laravel-scout-mysql-driver
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- damiantw/laravel-scout-mysql-driver v1.0.4 requires laravel/scout ^1.1 -> satisfiable by laravel/scout[v1.1.10, v1.1.11, v1.1.12, v1.1.3, v1.1.4, v1.1.5, v1.1.6, v1.1.7, v1.1.8, v1.1.9] but these conflict with your requirements or minimum-stability.
- damiantw/laravel-scout-mysql-driver v1.0.3 requires laravel/scout ^1.1 -> satisfiable by laravel/scout[v1.1.10, v1.1.11, v1.1.12, v1.1.3, v1.1.4, v1.1.5, v1.1.6, v1.1.7, v1.1.8, v1.1.9] but these conflict with your requirements or minimum-stability.
- damiantw/laravel-scout-mysql-driver v1.0.2 requires laravel/scout ^1.1 -> satisfiable by laravel/scout[v1.1.10, v1.1.11, v1.1.12, v1.1.3, v1.1.4, v1.1.5, v1.1.6, v1.1.7, v1.1.8, v1.1.9] but these conflict with your requirements or minimum-stability.
- damiantw/laravel-scout-mysql-driver v1.0.1 requires laravel/scout ^1.1 -> satisfiable by laravel/scout[v1.1.10, v1.1.11, v1.1.12, v1.1.3, v1.1.4, v1.1.5, v1.1.6, v1.1.7, v1.1.8, v1.1.9] but these conflict with your requirements or minimum-stability.
- damiantw/laravel-scout-mysql-driver v1.0.0 requires laravel/scout ^1.1 -> satisfiable by laravel/scout[v1.1.10, v1.1.11, v1.1.12, v1.1.3, v1.1.4, v1.1.5, v1.1.6, v1.1.7, v1.1.8, v1.1.9] but these conflict with your requirements or minimum-stability.
- Installation request for damiantw/laravel-scout-mysql-driver ^1.0 -> satisfiable by damiantw/laravel-scout-mysql-driver[v1.0.0, v1.0.1, v1.0.2, v1.0.3, v1.0.4].
Installation failed, reverting ./composer.json to its original content.
Hello. I use Laravel 5.3 upgraded to 5.4. I have PHP7 version and Mysql. I run my app on Ubuntu, apache2 machine.
I want search users using your package, when I try with only name (or last name) it's ok, but when I write name and last name, for example John Smith, I get issue.
ys_users
where MATCH(name,last_name,login,password,email,mobile,skype,street,city,file) AGAINST(John Smith IN BOOLEAN MODE))`Using version ^2.0 for yab/laravel-scout-mysql-driver
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Conclusion: don't install yab/laravel-scout-mysql-driver v2.0.3
- Installation request for laravel/scout (locked at v5.0.3, required as ^5.0) -> satisfiable by laravel/scout[v5.0.3].
- Conclusion: remove laravel/framework v5.6.31
- Conclusion: don't install laravel/framework v5.6.31
- yab/laravel-scout-mysql-driver v2.0.0 requires laravel/framework 5.3.|5.4. -> satisfiable by laravel/framework[5.3.x-dev, 5.4.x-dev].
- yab/laravel-scout-mysql-driver v2.0.1 requires laravel/framework 5.3.|5.4.|5.5.* -> satisfiable by laravel/framework[5.3.x-dev, 5.4.x-dev, 5.5.x-dev].
- yab/laravel-scout-mysql-driver v2.0.2 requires laravel/framework 5.3.|5.4.|5.5.* -> satisfiable by laravel/framework[5.3.x-dev, 5.4.x-dev, 5.5.x-dev].
- Can only install one of: laravel/framework[5.3.x-dev, v5.6.31].
- Can only install one of: laravel/framework[5.4.x-dev, v5.6.31].
- Can only install one of: laravel/framework[5.5.x-dev, v5.6.31].
- Installation request for laravel/framework (locked at v5.6.31, required as 5.6.*) -> satisfiable by laravel/framework[v5.6.31].
- Installation request for yab/laravel-scout-mysql-driver ^2.0 -> satisfiable by yab/laravel-scout-mysql-driver[v2.0.0, v2.0.1, v2.0.2, v2.0.3].
Installation failed, reverting ./composer.json to its original content.`
Is there any way to include or filter on the actual score?
MATCH(contents) AGAINST("TEST STRING" IN NATURAL LANGUAGE MODE)
from the WHERE clause can be repeated in the SELECT with an alias to get the score (this has no overhead according to MySQL docs)
MATCH(contents) AGAINST("TEST STRING" IN NATURAL LANGUAGE MODE) AS score
which also allows you to add something like "WHERE score > 2"
I tried looking through the code, but I can't figure out how to get to the QueryBuilder instance (for addSelect() method), but it seems Scout Builder doesn't expose this.
Any thoughts?
edit: Just want to add, that the main issue here is that all rows are always returned even ones that have a score of 0. This is not ideal.
Currently when you use the protected $appends array on your model the plugin searches for these names in your database as well resulting in Column not found: 1054
Getting "Undefined property: Laravel\\Scout\\Builder::$offset"
on line 73 in damiantw/laravel-scout-mysql-driver/src/Engines/MySQLEngine.php
which reads:
if($this->builder->offset) {
This happens when i do: Child::search($q)->get();
Using PHP 7.0.8 in homestead
composer.json
"laravel/scout": "^3.0", "damiantw/laravel-scout-mysql-driver": "^1.0"
Problem:
damiantw/laravel-scout-mysql-driver v1.0.7 requires laravel/scout ^2.0
Hello ,
i got a problem with the laravel 5.4 version , any update soon for that ?
Best
If in a model I use protected $appends
to add say a computed field like full_address
then you will get
Undefined offset: 0 {"exception":"[object] (ErrorException(code: 0): Undefined offset: 0 at .../vendor/yab/laravel-scout-mysql-driver/src/Services/ModelService.php:44)
Will submit a simple PR that will fix this now
How to make fulltext index on only one column? When I call php artisan scout:mysql-index it returns fulltext index from all text and varchar columns.
When I change to LIKE mode I'm getting an error showing that there are too many parameters.
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
"select count(*) as aggregate from recurring_profiles where account_id = :account_id AND (id LIKE :_search0 OR account_id LIKE :_search1 OR title LIKE :_search2) and recurring_profiles.deleted_at is null",
[
1,
"%liabiliti%",
"%liabiliti%",
"%liabiliti%",
"%liabiliti%"
],
Is there a way to include soft deleted models in the search results?
I tried several approached found around the net with no luck.
Maybe this is related to #17?
Getting this error:
Problem 1
- Conclusion: don't install yab/laravel-scout-mysql-driver v2.0.5
- Installation request for laravel/scout (locked at v5.0.3, required as ^5.0) -> satisfiable by laravel/scout[v5.0.3].
- Conclusion: remove laravel/framework v5.7.0
- Conclusion: don't install laravel/framework v5.7.0
First things first... Great Package!
I'm using it to perform searches on a website that is hosted on a shared server. Impossible to install other services like elasticsearch for example.
My Model has a lot of text fields and relations to other models. I tried all search modes but didn't achieve the results I need.
If I search for multiple words, I need to get the results that match all those words in any of the searchable fields. Unfortunately It search for each word and return all the records that have at least on of these words.
Example:
1-
Title: Table vintage
Body: beautiful furniture
2-
Title: modern table
Body: modern design
3-
Title: beautiful chair
Body: vintage design
Searching for "beautiful table" it returns all the items. How to get only the first one that has both words.
Is that possible with fulltext search?
Thanks for your help!
hi .if this Laravel Scout driver does not need to update any indexes and no cache record , what is the benefits of using this package ?
is it faster than eloquent queries ???
thank you
In response to #8, the database prefix is added to the $tableName
attribute of ModelService
(58aae1e). However, this prefix should only be added when executing SQL queries, not when using Laravel Database Builder functions like getColumnListing()
as the Builder automatically prefixes table names with the configurated db prefix.
My test returns this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '__soft_deleted' in 'where clause' (SQL: select count(*) as aggregate from `posts` where __soft_deleted = 0 AND MATCH(country,state,city,address,patient_avatar) AGAINST(Ismail IN NATURAL LANGUAGE MODE) and `posts`.`deleted_at` is null)
Any suggestion to solve this problem?
NB: I am using scout for first time.
I'm really into using Laravel 5.8 with this package :D
I wanted to use this package so that I can use the benefit of Laravel Scout
with MySql FULLTEXT. Instead of using raw full text query I used this package so that in future I can easily change the driver and if needed can use more efficient Search driver like elasticsearch
, TNTSearch
or algolia
.
I found many issue while installing and implementing it. But in the end I was able to install it successfully. For someone who may need this-
First, DamianTW\MySQLScout\Providers\MySQLScoutServiceProvider::class,
did not work for me it was showing error on running command. So I changes it to
Yab\MySQLScout\Providers\MySQLScoutServiceProvider::class,
The command php artisan scout:mysql-index App\\Post
didn't work for me. I changed it to
php artisan scout:mysql-index App\Post
. May be I am using windows ?
Now to allow only few selected table columns you should override toSearchableArray()
method in your model before running above command.
public function toSearchableArray()
{
// Customize array...
return [
'title' => $this->title,
'body' => $this->body,
];
}
Make sure your column is of type text
or varchar
To name the index name override searchableAs()
method in your model before running above command
public function searchableAs()
{
return 'search_index';
}
Note if you already have FULLTEXT
defined in your table then you can match the above value in searchableAs()
and toSearchableArray()
methods by providing exact same values.
Hope this help someone.
Let me know if it can be improved further or I need to make any correction
Getting Trait 'Illuminate\Console\DetectsApplicationNamespace' not found error when install and set the provider. After that i cant do the command php artisan vendor:publish. But if i comment the laravel-scout-mysql-driver provider the error is gone.
Laravel version is 5.3.18
Installed 6.0 and than try this package got with error
Would love to see Laravel 5.4 support.
Currently this happens when running
composer require damiantw/laravel-scout-mysql-driver
You gets
damiantw/laravel-scout-mysql-driver v1.0.6 requires laravel/framework 5.3.*
I am searching in few models, for example in tables 'posts' and 'categories'. In each separately relevance works good, but I get 2 collections, so order of rows depends on what collection I view first. Is there a way to get relevance attribute to sort merged collections by it?
[Illuminate\Database\QueryException] SQLSTATE[HY000]: General error: 1214 The used table type doesn't support FULLTEXT indexes (SQL: CREATE FULLTEXT INDEX companies ON companies (title))
Anyone who can help with this?) I can't figure it out!
Laravel: 5.5.18
Hi I was testing this package and see some strange behavoir with nullable columns.
I have this query:
Invoice::search('fox')
->where('exported', null)
->get();
This generates a query like this:
select * from `invoice` where exported = '' AND (`name` LIKE '%fox%')
What I expect:
select * from `invoice` where exported = null AND (`name` LIKE '%fox%')
This is incorrect... Also adding a extra parameter to the where is incorrect:
Invoice::search('fox')
->where('exported', '!=', null)
->get();
select * from `invoice` where exported = '!=' AND (`name` LIKE '%fox%')
What I expect:
select * from `invoice` where exported != null AND (`name` LIKE '%fox%')
Hi, my model has two MySQL date
columns, start_date
and end_date
stored as "Y-m-d", in addition to Laravel's created_at
and updated_at
.
In order for me to get them to display on the front end I need this line in my model:
protected $dates = ['start_date', 'end_date'];
I'm trying to integrate Laravel Scout with this driver but am running into an issue during index:
Creating index for App\Models\Report...
In Carbon.php line 582:
Data missing
Likewise, when trying to search the model I get this:
InvalidArgumentException
Data missing
The source of the problem seems to be these setters:
/*
* Convert start date to valid timestamp before adding to database.
*
* @param $value
*/
public function setStartDateAttribute($value)
{
$this->attributes['start_date'] = Carbon::createFromFormat('m/d/Y', $value);
}
/**
* Convert end date to valid timestamp before adding to database.
*
* @param $value
*/
public function setEndDateAttribute($value)
{
$this->attributes['end_date'] = Carbon::createFromFormat('m/d/Y', $value);
}
Which I use because the date picker data is flashed in the format m/d/Y
and then converted on persistence.
How can I get around this?
I have just updated to latest version of laravel/scout (5.0.3) and aravel-scout-mysql-driver (2.0.6) and i have started receiving the following error:
Declaration of Yab\MySQLScout\Engines\MySQLEngine::map(Laravel\Scout\Builder $builder, $model) must be compatible with Laravel\Scout\Engines\Engine::map(Laravel\Scout\Builder $builder, $results, $model)
When using global scopes, in my case based on user permission, and you want to disable those scopes for fetching, normally you can do something like:
$users = User::withoutGlobalScope(UserScope::class)->get();
When searching, it isn't possible to pass custom calls to the MySQL engine. A (very very very) ugly workaround is to overwrite the search
method to disable scopes before passing the model to the engine:
public static function search(string $query, $callback = null): Collection
{
// Temporary disable global scopes
static::$globalScopes = [];
$results = (new ScoutBuilder(new static(), $query, $callback))->get();
static::addGlobalScope(new UserScope());
return $results;
}
Any other ideas how to resolve this in a more elegant way?
Hi,
Do you have any plan to support laravel 5.6?
Thank You
$searchText = 'test';
$query_builder = User::search($searchText);
$query_builder->where('a <=', 10);
$query_builder->where('b >=', 100);
it's correct, result :
select count(*) as aggregate from `beats` where a< '10' AND b> '100'
AND MATCH(title) AGAINST('test' IN NATURAL LANGUAGE MODE)
but if i do
$searchText = 'test';
$query_builder = User::search($searchText);
$query_builder->where('a <=', 10);
$query_builder->where('a >=', 100);
result
"Illuminate\Database\QueryException
SQLSTATE[HY093]: Invalid parameter number (SQL: select count(*) as aggregate
from `users` where a<= 100 AND a>= test AND MATCH(title) AGAINST(? IN NATURAL LANGUAGE MODE))
QueryException in Connection.php line 761:
SQLSTATE[HY000]: General error: 1191 Can't find FULLTEXT index matching the column list (SQL: select count(*) as aggregate from company_specs
where MATCH(spec_no,name) AGAINST(:_search IN NATURAL LANGUAGE MODE))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.