I'm currently trying to implement a search in my db for keywords. Therefore I split a string seperated by a comma, so I get an array containing a variable number of elements (one keyword).
I know that I can use a eloquent construct like that:
$products = Product::where([['keywords', 'LIKE', %samsung%], [keywords, 'LIKE', 's7']])->paginate(15);
to find a product with the keywords samsung,galaxy,s7.
Now I need this thing but automatically generated for a variable number of search query parts, so for every keyword in the array I need to add one ['keywords', 'LIKE', '...']...
How can I do this with Laravels Eloquent?
Use closure. First, make sure you stored list of keywords into array or the like. Then ...
$keywords = ['samsung', 's7', 'what else'];
$products = Product::where(function ($query) use ($keywords) {
foreach ($keywords as $keyword) {
$query->orWhere('keyword', 'like', $keyword);
}
})->paginate(15);
other example
$keywords = [
['name', 'LIKE', $searchQuery],
['category_id', '=', $selectedSubcategory],
];
$products = Product::where(function ($query) use ($keywords) {
foreach ($keywords as $keyword) {
$query->where($keyword);
}
})->paginate(15);
other than other
$keywords = [
['name', 'LIKE', $searchQuery],
['category_id', '=', $selectedSubcategory],
['please_id', '=', $learnPhpArray],
];
$products = Product::query();
foreach ($keywords as $keyword) {
$products = $products->where($keyword);
}
return $products->paginate(15);
What does the orWhere do? Does it connect the query parts with a AND?
No, with OR. As the inverse(?) the where itself does AND by default.
References
https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Builder.html#method_where
https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Builder.html#method_orWhere
Isn't it just to generate the array? Or am I misunderstanding the question?
<?php
$keys = ['samsung', 'lg', 'sony', 'nokia', 'apple'];
$keywords = [];
foreach($keys as $key){
$keywords[] = ['keywords', 'LIKE', '%'.$key.'%'];
}
$products = Product::where($keywords)->paginate(15);
You can do this:
$query = "Samsung galaxy S7"; // Or whatever the query is
$words = preg_split("/[ ,.]/",$query); //Split on space comma or dot. Maybe need more?
$queries = array_map(function ($word) {
return [ "keywords", "LIKE", "%$word%" ];
}, $words); //Transform single words to array of queries
$products = Product::where($queries)->paginate(15);
Check how the first part of the code works at: https://eval.in/730772
laravel 5.6
$keyWords = KeyWordModel::all();
$keyWordQuerys = [];
foreach ($keyWords as $key => $item) {
$keyWordQuerys[$key] = ['title', 'like', '%'.$item->name.'%'];
}
$contents = ContentModel::query();
foreach ($keyWordQuerys as $key => $item) {
$contents = $contents->orwhere([$item]);
}
$contents = $contents->orderBy('pubDate', 'DESC')->get();
Related
I have tried to trim "appointment" to check if it is equal to string that I have sent by trim function from ajax. But trim('appointment') doesn't give me what I need. How can delete whitespaces from object in sql to check some condition using where
public function category_filter(Request $request)
{
$appointment = json_decode($request->appointment);
$categories = [];
foreach($appointment as $a){
$cat_c_id = Products::where(trim('appointment'), '=', $a)->select('id')->get();
foreach($cat_c_id as $cat_c){
array_push($categories, $cat_c);
}
}
var_dump($categories);
}
The correct answer here is to fix your data and not store it with whitespace in the first place. Failing that, you need to use a raw statement:
public function category_filter(Request $request)
{
$appointment = json_decode($request->appointment);
$categories = [];
foreach($appointment as $a) {
$cat_c_id = Products::whereRaw('TRIM(appointment) = ?', [$a])
->select('id')
->get();
foreach($cat_c_id as $cat_c){
array_push($categories, $cat_c);
}
}
var_dump($categories);
}
Taking it a step further, you are performing pointless foreach loops that can be replaced with something like this:
public function category_filter(Request $request)
{
$appointment = json_decode($request->appointment);
// build a string like TRIM(appointment) IN (?,?,?,?)
$raw = 'TRIM(appointment) IN (' . implode(',', array_fill(0, count($appointment), '?')) . ')';
$categories = Products::whereRaw($raw, $appointment)
->select('id')
->get()
->toArray();
}
var_dump($categories);
}
trim('appointment') //this will trim the string 'appointment', not its value on table
try this (considering that Products::where allow this type of implementation):
...
$cat_c_id = Products::where('trim(appointment)', '=', trim($a))->select('id')->get();
...
I am not sure how to say this, but you will get the idea from the below code. Laravel framework is used.
My code is as shown below:
$keywords = ProductKeyword::orderBy('name', 'asc')->pluck('name')->toArray();
if (!empty($keywords)) {
$str = '';
foreach ($keywords as $key => $keyword) {
if ($key == 0) {
$str .= "Where('description', 'like', '%' . $keyword . '%')";
} else {
$str .= "->orWhere('description', 'like', '%' . $keyword . '%')";
}
}
}
$str .= "->all()";
$items = Item::$str;
dd($items);
I need the value of $str to be appended to Item model, so that in effect the php interprets this as below
$items = Item::Where('description', 'like', '%' . 'laptop' . '%')->orWhere('description', 'like', '%' . 'pc' . '%')->all();
So that I can dynamically create where-clauses.
You are overcomplicating things a little here. Grab the collection of keywords, and iterate those, then use orWhere() on the keywords name, and voila. Open up a query on your items with the query() method, then apply orWhere() for each iteration. Laravel will handle the rest. Once done, you just need to get() your data!
$keywords = ProductKeyword::orderBy('name', 'asc')->get();
$items = Item::query();
foreach ($keywords as $key => $keyword) {
$items->orWhere('description', 'like', '%'.$keyword->name.'%');
}
$items = $items->get();
dd($items);
Note that if there are no keywords, it will essentially become Item::all(), since you do not apply any where-clauses.
you need to improve and fix your code:
$query = Item::query();
foreach ($keywords as $keyword) {
$query->orWhere('description', 'like', '%'.$keyword.'%');
}
$result=$query->get();
you are using a complex way to achieve it. my answer would be almost same as #Qirel
//prepare your query
$query = Item::query();
foreach ($keywords as $keyword) {
//loop through the keywords in the description column of Item Table match the records which will be available in the $query
$query->orWhere('description', 'like', '%'.$keyword.'%');
}
// get the records which are matched and store it in $result variable
$result=$query->get();`enter code here`
There are many matching credentials inside the table which are inserted to an foreach loop however I am getting the results only from the first foreach element. How could I fix that?
foreach($matches as $match)
{
$object = $match->object;
$sales->whereRaw("match (`object`) against (?)", array($object));
if($match->colourBase == '1')
{
$sales->where('colour', '=', 'CC');
$sales->orWhere('colour', '=', 'CC+DD');
if($match->maxPrice)
{
$sales->where('price', '<=', $match->maxPrice);
}
if($match->minPrice)
{
$sales->where('price', '>=', $match->minPrice);
}
}
}
$results = $sales->orderBy('sales.updated_at', 'asc')->get();
#update
This is how I get $matches
$matches = Match::where('PeopleID', '=', $id)->get();
If you want only one record
use first() function.
No need to use foreach. :)
$matches = Match::where('PeopleID', '=', $id)->first();
So I have this code
$Input = Input::all();
$makethis = Input::flash();
$soptions = Input::get('soptions');
$items = Gamefarm::where('roost_hen', '=',Input::get('sex'))
->where('bname', 'LIKE', '%$soptions%')
->paginate(6);
What I want to do is for laravel to accept the value inside the $soptions. When I tried hard coding the $soptions it works fine.
One more question
$Input = Input::all();
$makethis = Input::flash();
$textbox = Input::get('searchbox');
$soptions = Input::get('soptions');
var_dump($soptions);
$items = Gamefarm::where('roost_hen', '=', Input::get('sex'))
->where($soptions, 'LIKE', "$textbox")
->paginate(6);
return View::make('gamefarms/index', compact('items','makethis'));
Now what I want to do is use the variable $soptions to be the query's field name, I get an error 500 when I do this
This '%$soptions%' does not get interpolated, instead you should write "%$soptions%" or "%{$soptions}%" or '%' . $soptions . '%'. Simple mistake.
I am trying to create a search feature for my back-end in Laravel 4 , where I can search for users by ( firstname , lastname , email). I have this function so far but it's not really working :
public function searchUser()
{
$search = Input::get('search');
$searchTerms = explode(' ', $search);
foreach($searchTerms as $term)
{
$query = User::Where('firstname', 'LIKE', '%'. $term .'%');
}
$results = $query->get();
}
How do I get the others like lastname, email in there?
You can do this:
<?php
public function searchUser()
{
$search = Input::get('search');
$searchTerms = explode(' ', $search);
$query = User::query();
$fields = array('first_name', 'last_name', 'email');
foreach ($searchTerms as $term)
{
foreach ($fields as $field)
{
$query->orWhere($field, 'LIKE', '%'. $term .'%');
}
}
$results = $query->get();
}
This way it will do a LIKE query of all search terms in all fields.
You also can paginate it by doing:
$result = $query->paginate(10);