Laravel/PostgreSQL query with non-capitalised letters - sql

I am doing a Laravel CRUD exercise and I have set up a search route in the controller:
public function search($name)
{
return Product::where('name', 'like', '%'.$name.'%')->get();
}
And on the backend psql database, I have an item name exactly as iPhone 11.
When I ran a query on postman, it worked fine if I GET by localhost:8000/api/products/search/iPh. However, if I uncapitalised it as ...search/iph, it would return an empty array.
So my question is, what do I do so I can search with uncapitalised letters while the data stored contains capitalised letters?

For MySQL you can use raw query
Product::whereRaw("UPPER(name) LIKE '%'". strtoupper($name)."'%'")->get();
For pgSQL you can use ILIKE for case in-sensitive and LIKE for case sensitive
Product::where('name', 'ILIKE', '%'.$name.'%')->get();

Related

Select $id from ids field containg $id1,$id2,$id3

My model in Laravel has a linked_ids string field like this:
echo $model->linked_ids
1,2,3,4,5
I want to make a query that gets me all records with a given id in linked_ids.
Currently I have:
Model::where('linked_ids', 'LIKE', '%' . $model->id . '%');
but this selects me more than I want to (if ex: $model->id is 3 => selects: 1,32,67)\
How can I avoid this since I don't know what position the id will be nor will the ids be ordered? I would like to do this in eloquent but can also use something like DB::raw() to run sql queries.
Bad way to keep your ids but if you really can't change it, you could take advantage of LazyCollections and filter with php.
I'm sure there's a way to do it directly in MySQL (or whatever dbms you're using) but this is what I have.
$id = 3;
Model::cursor()
->filter(function ($model) use ($id) {
return in_array($id, explode(',', $model->linked_ids));
})
// then chain one of these methods
->first(); // returns the first match or null
->collect(); // returns an Illuminate\Support\Collection of the results after the filtering
->all(); // returns an array of Models after the filtering
->toArray(); // returns an array and transforms the models to arrays as well.
->toJson(); // returns a json string
Take notice that this will still do a SELECT * FROM table without any filtering (unless you chain some where methods before cursor() but it won't load any model into memory (which is usually the bottleneck for big queries in Laravel)

API parameters - filter with ARRAY_CONTAINS (cosmos db back end)

I have an API I am pinging which queries a cosmos db to return records.
I can filter on a simple string in my api call like so:
// return objects where '_Subject' field equals "filterTest"
string getUrl = $"...baseApiPath/?$filter=_Subject+eq+'filterTest'";
This is working perfectly.
But I cannot figure out the filter syntax to make my API query be based on ARRAY_CONTAINS.
// return objects where '_Attachments' field CONTAINS "945afd138aasdf545a2d1";
How would I do that? Is there a general reference for API filter syntax somewhere?
If you're asking about how to query, a query against a property with an array of values looks like this:
SELECT * FROM c WHERE ARRAY_CONTAINS(c._Attachments, "945afd138aasdf545a2d1")
Another example in this answer.

ArangoDB AQL Non Case Sensitive Comparison

Let's imagine I have a few simple docs stored in an Arango collection like so:
[
{"type":Cat, "quality":Fuzzy}
{"type":Dog, "quality":Barks}
{"type":Rabbit, "quality":Hoppy}
{"type":Pig, "quality":Chubby}
{"type":Red Panda, "quality":Fuzzy}
{"type":Monkey, "quality":Hairy}
]
Now let's say a user initiates a search in my application for all animals that are 'fuzzy', all lower case. Is there a way with AQL to make a comparison that is not case sensitive? So for instance:
FOR a IN animals
FILTER a.type.toLowerCase() == fuzzy
RETURN a
Now I know the above example doesn't work, but it would be nice if there was a way to do this. Thanks!
There is a LOWER string function in AQL which you can try to use in your query like this:
FOR a IN animals
FILTER LOWER(a.quality) == 'fuzzy'
RETURN a

Entity Framework Dynamic Lambda to Perform Search

I have the following entities in Entity Framwork 5 (C#):
OrderLine - Id, OrderId, ProductName, Price, Deleted
Order - Id, CustomerId, OrderNo, Date
Customer - Id, CustomerName
On the order search screen the user can enter the following search values:
ProductName, OrderNo, CustomerName
For Example they might enter:
Product Search Field: 'Car van bike'
Order Search Field: '100 101 102'
Customer Search Field: 'Joe Jack James'
This should do a OR search (ideally using linq to entities) for each entered word, this example would output the following where sql.
(ProductName like 'Car' Or ProductName like 'van' Or ProductName like 'bike') AND
(OrderNo like '100' Or OrderNo like '101' Or OrderNo like '102') AND
(CustomerName like 'Joe' Or CustomerName like 'Jack' Or CustomerName like 'James')
I want to do this using linq to entities, i am guessing this would need to be some sort of dynamic lambda builder as we don't know how many words the user might enter into each field.
How would i go about doing this, i have had a quick browse but cant see anything simple.
You can build a lambda expression using Expression Trees . What you need to do is split the value and build the expression . Then you can convert in in to a lambda expression like this,
var lambda = Expression.Lambda<Func<object>>(expression);
Here is an example
There are 2 basic approaches to Dynamic Expressions and Queries in LINQ.
3 if you count using Json as the approach to get a lambda expression. => Akash Kava post
a) String Dynamic Lambda
System.Linq.Dynamic can be found at following links
http://msdn.microsoft.com/en-US/vstudio/bb894665.aspx
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
http://www.scottgu.com/blogposts/dynquery/dynamiclinqcsharp.zip
b) Build Expression trees
More powerful but harder to master...
Build expressions trees with code found here:
http://msdn.microsoft.com/en-us/library/system.linq.expressions.aspx
an alternate approach is predicate builder but it isnt really that dynamic.
but can deal with the OR type scenario you give as example.
http://www.albahari.com/nutshell/predicatebuilder.aspx
I would recomend to go slightly different way from answers above and use EntitySQL as it is trivial to build SQL-like string with dynamic conditions.
http://msdn.microsoft.com/en-us/library/bb738683.aspx
Disclaimer: I am author of Entity REST SDK.
You can look at Entity REST SDK at http://entityrestsdk.codeplex.com
You can query using JSON syntax as shown below,
/app/entity/account/query?query={AccountID:2}&orderBy=AccountName
&fields={AccountID:'',AcccountName:''}
You can use certain extensions provided to convert JSON to lambda.
And here is details of how JSON is translated to Linq. http://entityrestsdk.codeplex.com/wikipage?title=JSON%20Query%20Language&referringTitle=Home
Current Limitations of OData v3
Additionally, this JSON based query is not same as OData, OData does not yet support correct way to search using navigation properties. OData lets you search navigation property inside a selected entity for example Customer(1)/Addresses?filter=..
But here we support both Any and Parent Property Comparison as shown below.
Example, if you want to search for List of Customers who have purchased specific item, following will be query
{ 'Orders:Any': { 'Product.ProductID:==': 2 } }
This gets translated to
Customers.Where( x=> x.Orders.Any( y=> y.Product.ProductID == 2))
There is no way to do this OData as of now.
Advantages of JSON
When you are using any JavaScript frameworks, creating query based on English syntax is little difficult, and composing query is difficult. But following method helps you in composing query easily as shown.
function query(name,phone,email){
var q = {};
if(name){
q["Name:StartsWith"] = name;
}
if(phone){
q["Phone:=="] = phone;
}
if(email){
q["Email:=="] = email;
}
return JSON.stringify(q);
}
Above method will compose query and "AND" everything if specified. Creating composable query is great advantage with JSON based query syntax.

ActiveRecord search model using LIKE only returning exact matches

In my rails app I am trying to search the Users model based on certain conditions.
In particular, I have a location field which is a string and I want to search this field based on whether it contains the search string. For example, if I search for users with location 'oxford' I want it to also return users with a variation on that, like 'oxford, england'.
Having searched the web for the answer to this it seems that I should be using the LIKE keyword in the activerecord search, but for me this is only returning exact matches.
Here is a snippet of my code from the search method
conditions_array = []
conditions_array << [ 'lower(location) LIKE ?', options[:location].downcase ] if !options[:location].empty?
conditions = build_search_conditions(conditions_array)
results = User.where(conditions)
Am I doing something wrong? Or is using LIKE not the right approach to achieving my objective?
You need to do like '%oxford%'
% Matches any number of characters, even zero characters
conditions_array << [ 'lower(location) LIKE ?', "%#{options[:location].downcase}%" ] if !options[:location].empty?