You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
8.5 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. Laravel 5+ Searchy
  2. ========================================
  3. ### Database Searching Made Easy
  4. Searchy is an; easy-to-use, light-weight, MySQL only, Laravel package that makes running user driven searches on data in your models simple and effective.
  5. It uses pseudo fuzzy searching and other weighted mechanics depending on the search driver that you have enabled.
  6. It requires no other software installed on your server (so can be a little slower than dedicated search programs) but can be set up and ready to go in minutes.
  7. #### !! Laravel 4 !!
  8. Looking for Laravel 4 compatible Searchy? Checkout the 1.0 branch :)
  9. Installation
  10. ----------------------------------------
  11. Add `"tom-lingham/searchy" : "2.0"` to your composer.json file under `require`:
  12. ```
  13. "require": {
  14. "laravel/framework": "5.*",
  15. "tom-lingham/searchy" : "2.0"
  16. }
  17. ```
  18. Run `composer update` in your terminal to pull down the package into your vendors folder.
  19. Add the service provider to the `providers` array in Laravel's app/config/app.php file:
  20. ```php
  21. TomLingham\Searchy\SearchyServiceProvider::class
  22. ```
  23. Add the Alias to the `aliases` array in Laravel's app/config/app.php file if you want to have quick access to it in your application:
  24. ```php
  25. 'Searchy' => TomLingham\Searchy\Facades\Searchy::class
  26. ```
  27. Usage
  28. ----------------------------------------
  29. To use Searchy, you can take advantage of magic methods.
  30. If you are searching the name and email column/field of users in a `users` table you would, for example run:
  31. ```php
  32. $users = Searchy::users('name', 'email')->query('John Smith')->get();
  33. ```
  34. you can also write this as:
  35. ```php
  36. $users = Searchy::search('users')->fields('name', 'email')->query('John Smith')->get();
  37. ```
  38. In this case, pass the columns you want to search through to the `fields()` method.
  39. These examples both return an array of Objects containing your search results. You can use `getQuery()` instead of
  40. `get()` to return an instance of the Database Query Object in case you want to do further manipulation to the results:
  41. ```php
  42. $users = Searchy::search('users')->fields('name', 'email')->query('John Smith')
  43. ->getQuery()->having('relevance', '>', 20)->get();
  44. ```
  45. #### Searching multiple Columns
  46. You can also add multiple arguments to the list of fields/columns to search by.
  47. For example, if you want to search the name, email address and username of a user, you might run:
  48. ```php
  49. $users = Searchy::users('name', 'email', 'username')->query('John Smith')->get();
  50. ```
  51. #### Searching Joined/Concatenated Columns
  52. Sometimes you may want to leverage searches on concatenated column. For example, on a `first_name` and `last_name` field but you only want to run the one query. To do this can separate columns with a double colon:
  53. ```php
  54. $users = Searchy::users('first_name::last_name')->query('John Smith')->get();
  55. ```
  56. #### Return only specific columns
  57. You can specify which columns to return in your search:
  58. ```php
  59. $users = Searchy::users('first_name::last_name')->query('John Smith')->select('first_name')->get();
  60. // Or you can swap those around...
  61. $users = Searchy::users('first_name::last_name')->select('first_name')->query('John Smith')->get();
  62. ```
  63. This will, however, also return the `relevance` aliased column regardless of what is entered here.
  64. Configuration
  65. ----------------------------------------
  66. You can publish the configuration file to your `app` directory and override the settings by running `php artisan config:publish tom-lingham/searchy`
  67. You can set the default driver to use for searches in the configuration file. Your options (at this stage) are: `fuzzy`, `simple` and `levenshtein`.
  68. You can also override these methods using the following syntax when running a search:
  69. ```php
  70. Searchy::driver('fuzzy')->users('name')->query('Batman')->get();
  71. ```
  72. Drivers
  73. ----------------------------------------
  74. Searchy takes advantage of 'Drivers' to handle matching various conditions of the fields you specify.
  75. Drivers are simply a specified group of 'Matchers' which match strings based on specific conditions.
  76. Currently there are only three drivers: Simple, Fuzzy and Levenshtein (Experimental).
  77. #### Simple Search Driver
  78. The Simple search driver only uses 3 matchers each with the relevant multipliers that best suited my testing environments.
  79. ```php
  80. protected $matchers = [
  81. 'TomLingham\Searchy\Matchers\ExactMatcher' => 100,
  82. 'TomLingham\Searchy\Matchers\StartOfStringMatcher' => 50,
  83. 'TomLingham\Searchy\Matchers\InStringMatcher' => 30,
  84. ];
  85. ```
  86. #### Fuzzy Search Driver
  87. The Fuzzy Search Driver is simply another group of matchers setup as follows. The multipliers are what I have used, but feel free to change these or roll your own driver with the same matchers and change the multipliers to suit.
  88. ```php
  89. protected $matchers = [
  90. 'TomLingham\Searchy\Matchers\ExactMatcher' => 100,
  91. 'TomLingham\Searchy\Matchers\StartOfStringMatcher' => 50,
  92. 'TomLingham\Searchy\Matchers\AcronymMatcher' => 42,
  93. 'TomLingham\Searchy\Matchers\ConsecutiveCharactersMatcher' => 40,
  94. 'TomLingham\Searchy\Matchers\StartOfWordsMatcher' => 35,
  95. 'TomLingham\Searchy\Matchers\StudlyCaseMatcher' => 32,
  96. 'TomLingham\Searchy\Matchers\InStringMatcher' => 30,
  97. 'TomLingham\Searchy\Matchers\TimesInStringMatcher' => 8,
  98. ];
  99. ```
  100. #### Levenshtein Search Driver (Experimental)
  101. The Levenshtein Search Driver uses the Levenshetein Distance to calculate the 'distance' between strings. It requires that you have a stored procedure in MySQL similar to the following `levenshtein( string1, string2 )`. There is an SQL file with a suitable function in the `res` folder - feel free to use this one.
  102. ```php
  103. protected $matchers = [
  104. 'TomLingham\Searchy\Matchers\LevenshteinMatcher' => 100
  105. ];
  106. ```
  107. Matchers
  108. ----------------------------------------
  109. #### ExactMatcher
  110. Matches an exact string and applies a high multiplier to bring any exact matches to the top.
  111. #### StartOfStringMatcher
  112. Matches Strings that begin with the search string.
  113. For example, a search for 'hel' would match; 'Hello World' or 'helping hand'
  114. #### AcronymMatcher
  115. Matches strings for Acronym 'like' matches but does NOT return Studly Case Matches
  116. For example, a search for 'fb' would match; 'foo bar' or 'Fred Brown' but not 'FreeBeer'.
  117. #### ConsecutiveCharactersMatcher
  118. Matches strings that include all the characters in the search relatively positioned within the string. It also calculates the percentage of characters in the string that are matched and applies the multiplier accordingly.
  119. For Example, a search for 'fba' would match; 'Foo Bar' or 'Afraid of bats', but not 'fabulous'
  120. #### StartOfWordsMatcher
  121. Matches the start of each word against each word in a search.
  122. For example, a search for 'jo ta' would match; 'John Taylor' or 'Joshua B. Takeshi'
  123. #### StudlyCaseMatcher
  124. Matches Studly Case strings using the first letters of the words only
  125. For example a search for 'hp' would match; 'HtmlServiceProvider' or 'HashParser' but not 'hasProvider'
  126. #### InStringMatcher
  127. Matches against any occurrences of a string within a string and is case-insensitive.
  128. For example, a search for 'smi' would match; 'John Smith' or 'Smiley Face'
  129. #### TimesInStringMatcher
  130. Matches a string based on how many times the search string appears inside the string it then applies the multiplier for each occurrence.
  131. For example, a search for 'tha' would match; 'I hope that that cat has caught that mouse' (3 x multiplier) or 'Thanks, it was great!' (1 x multiplier)
  132. #### LevenshteinMatcher
  133. See *Levenshtein Driver*
  134. Extending
  135. ----------------------------------------
  136. #### Drivers
  137. It's really easy to roll your own search drivers. Simply create a class that extends `TomLingham\Searchy\SearchDrivers\BaseSearchDriver` and add a property called `$matchers` with an array of matcher classes as the key and the multiplier for each matcher as the values. You can pick from the classes that are already included with Searchy or you can create your own.
  138. #### Matchers
  139. To create your own matchers, you can create your own class that extends `TomLingham\Searchy\Matchers\BaseMatcher` and (for simple Matchers) override the `formatQuery` method to return a string formatted with `%` wildcards in required locations. For more advanced extensions you may need to override the `buildQuery` method and others as well.
  140. Contributing & Reporting Bugs
  141. ----------------------------------------
  142. If you would like to improve on the code that is here, feel free to submit a pull request.
  143. If you find any bugs, submit them here and I will respond as soon as possible. Please make sure to include as much information as possible.