Laravel sql search json type column - php

The mysql has table 'subscribe' table and it's as follows:
column type
id int
condition json
type_id id
and the example as follows:
"id": "1",
"condition": "{\"id\":\"2\",\"class\":\"master\",\"zone\":\"west\",\"price\":\"511\"}",
"type_id": "1"
and I want to select the column which match in the column condition like "zone"="west"
the laravel 5.2 has support the order
$subscribe = DB::table('subscribe')->where('condition->class', 'master')->get();
Error
Column not found: 1054 Unknown column 'condition->class' in 'where clause'(
SQL: select * from `subscribe` where `condition->class` = master)
I need is get the term which match the condition where conditon->class = master .I need to select the data which match the need in the model.
I don't know what's wrong. Any help would be much appreciated.

I believe the correct syntax is:
$subscribe = DB::table('subscribe')->where('condition->"$.class"', 'master')->get();
See the example below this paragraph, on https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html
column->path
In MySQL 5.7.9 and later, the -> operator serves as an alias for the JSON_EXTRACT() function when used with two arguments, a column identifier on the left and a JSON path on the right that is evaluated against the JSON document (the column value). You can use such expressions in place of column identifiers wherever they occur in SQL statements.

The thing is the where clause in query is considering as a column name in condition->class and not as a laravel code. you want to extract the value from json. but the query doesn't understand that.
What you need to do is pass entire table as it is in json format to the view and then extract in the view.
I suggest do something like this :
Here, $subscribe has entire table in json . which you can access it by :
$subscribe = DB::table('subscribe')->all();
return response()->json(array('subscribe' => $subscribe));
Then in the view do:
#if($subscribe->condition->class == 'master')
id : {{ $subscribe->id }}
type id : {{ $subscribe->type_id }}
#endif
Updated Code
//get condition in json
$subscribe = DB::table('subscribe')->select('condition')->get();
then,
// convert json to array
$subscribe_array = json_decode($subscribe, true);
// create a new collection instance from the array
$collection_array = collect($subscribe_array);
if($collection_array['class'] == 'master')
{
//do something
}
Something like this do the trick

Related

Test JSON data from database and get the column

I have in my database a column which store a json and I would like to recover the value of a certain object of my json in order to test it
So my column "JSON" contains that
{
"type":"index",
"data ":{"index":2}
}
And if i receive 2, i need to get this column which contain the index 2 to delete it
I have tried this:
$column = Table::where('JSON["data"]["index"]','=', '2' )
->first();
Table::dropColumn($column);
But it doesn't work, beacause i can't get the index
If you are using latest laravel version then,
$column = Table::where('JSON->data->index','2')->first();
Should work.
You can refer official laravel documentation for json where clause here.
Simply use SQL Like
->where('JSON', 'like', '%"index": "2"%');
Since you gave JSON value as a string, it was unable to get the index value.
Can you please try like below,
$column = Table::whereRaw(JSON["data"]["index"], '=', '2' )
->first();
Table::dropColumn($column);

In mongoDB query with lumen : $or/$and/$nor entries need to be full objects

In my MongoDB, I have stored value as below,
{
"_id" : ObjectId("5bed3f5019f0431be000412b"),
"reference" : "SL2PR01MB2745E4160158C08C4B7A367285C30#SL2PR01MB2745.apcprd01.prod.exchangelabs.com,SL2PR01MB274333160158C08C4B7A367285C30#SL2PR01MB2745.apcprd01.prod.exchangelabs.com",
"email_thread_id" : NumberInt(5)
}
{
"_id" : ObjectId("5bed3f5019f0431be000412b"),
"reference" : "SL2PR01MB2745E4160158C08C4B7A364444C30#SL2PR01MB2745.apcprd01.prod.exchangelabs.com",
"email_thread_id" : NumberInt(6)
}
My search keyword is:
"SL2PR01MB2745E4160158C08C4B7A364444C30#SL2PR01MB2745.apcprd01.prod.exchangelabs.com"
Which is match with second array from above JSON.
This is my query,
$referanceId= "SL2PR01MB2745E4160158C08C4B7A364444C30#SL2PR01MB2745.apcprd01.prod.exchangelabs.com";
$mailExists = DB::connection('mongodb')->collection('email_message')
->select('email_thread_id');
if ($referanceId) {
$mailExists->whereRaw("find_in_set(".$referanceId.", reference)");
}
$query = $mailExists->first();
But it gives me error like below:
ServerException in Find.php line 299:
$or/$and/$nor entries need to be full objects
Please help me to resolve this issue. Thank you.
You can do this easier with the laravel where method, this will do the comparison you want, and also make your code better readable.
You can use the following query to accomplish this:
DB::connection('mongodb')->collection('email_message')
->where("reference", $referanceId)->first();
If your value contains multiple reference id's as a string you can use:
$regexQuery = '/.*'.$referanceId.'.*/';
DB::connection('mongodb')->collection('email_message')
->where("reference", 'regexp', $regexQuery)->first();
This will match the referenceId in any position in the string.
As #hetalgotel mentioned in the comments another query for this is:
$mailExists->where("reference", 'like', "%$referanceId%")
This one produced the expected result in this scenario

Laravel : Query to get a single column in response from a JSON column in mysql 5.7

I have a mysql database (5.7.1) with a table "inventory" containing 2 columns :
id {String}
content {json}
The content column contains a json with severals keys:
{
"id" : "myId",
"arrayOfEl" : [
{id : "1", always : true},
{id : "1", always : true}
]
}
I try to make a query in laravel to get only the arrayOfEl keys from the content column of the specified id:
$inventory = Inventory::where('id', "myId")->get(????);
How don't know where specify in the query to get only the sub-column arrayOfEl in response ?
Unless your table is json type, you might need to fetch the whole rows then try to filter them. Make sure you define attribute casting on the model, example here using collection
protected $casts = [
'arrayOfEl' => 'collection',
];
And then try to find match
$myId = 'myId'; // id of content
$inventory = Inventory::all()->filter(function ($item) use ($myId) {
return is_object($item->content) && $item->content->id == $myId;
})->first();
Or if you have json type column. You can simply filter it based on -> notation.
->where('content->id', 'myId')
You can use pluck to get only the columns you need.
$inventory = Inventory::where('id', 'myId')->pluck('arrayOfEl');

How to compare against fields that are `null` (empty)?

I have a table in a CakePHP 3 application called downloads which has a column called master. The field type is set to TINYINT(1)
I can find any records where downloads.master == 1 like this:
$query = $this->Downloads->find()->where(['master' => true]);
But Cake won't let me query for ones where downloads.master !== 1. None of these work, and all return an empty array/object when the query is executed:
$query = $this->Downloads->find()->where(['master' => false]);
$query = $this->Downloads->find()->where(['master' => 0]);
$query = $this->Downloads->find()->where(['master' => null]);
$query = $this->Downloads->find()->where(['master' => '']);
What do you use as the condition to make this possible? My thinking was that it should be false since that's the opposite to true, but as with most things in CakePHP 3 they like to make it more complicated than necessary...
I've examined the records in my table using phpMyAdmin and there are indeed both records where master == 1 and master == null so it's not a case of there's zero results to return.
A column being NULL is not the same as being 0 (ie false-ish from the point of view of the ORM in case of a boolean-ish column type). If you want to compare against NULL, then you must issue a query with IS NULL, which is a SQL/DBMS requirement, not a CakePHP requirement.
CakePHP however requires you to be specific about what you want to do, as passing null does not neccesarily have to mean that you want to compare against SQL NULL, depending on the context.
Long story short, use the IS operator:
where(['master IS' => null])
Similarly use IS NOT for a negated condition. You can also pass user input as the value, the ORM will test the value and convert the IS and IS NOT operators into = and != respectively in case a non-null value is being passed.
See also
Cookbook > Database Access & ORM > Query Builder > Automatic IS NULL Creation

Laravel 5 eloquent model won't let me update

I do have the invitations table set up and in the database. I use it for other purpose such as adding more...
my goal: update the first record with a new value to a field:
I tried:
$invitation = new MemberInvitation();
$invitation1 = $invitation->find(1);
$invitation1->status = 'clicked';
$invitation1->save();
And also:
$invitation1 = \App\Model\MemberInvitation::find(1);
$invitation1->status = 'clicked';
$invitation1->save();
both ended with:
Creating default object from empty value
EDIT:
This piece of code worked and updated my records correctly -- I just can't do it via Eloquent's model:
\DB::table('member_invitations')->where('id', '=', $member_invitation->id)
->update(array('status' => 'clicked', 'member_id' => $member->id));
what am I missing?
Try this.
$invitation = MemberInvitation::findOrFail(1);
$invitation->status = 'clicked';
$invitation->save();
If that doesnt work, please show your model
find(1) doesn't mean "give me the first record", it means "give me the first record where id = 1". If you don't have a record with an id of 1, find(1) is going to return null. When you try and set an attribute on null, you get a PHP warning message "Creating default object from empty value".
If you really just want to get the first record, you would use the first() method:
$invitation = \App\Model\MemberInvitation::first();
If you need to get a record with a specific id, you can use the find() method. For example, to translate your working DB code into Eloquent, it would look like:
$invitation = \App\Model\MemberInvitation::find($member_invitation->id);
$invitation->status = 'clicked';
$invitation->member_id = $member->id;
$invitation->save();
The answer is obvious based on your reply from May 15th.
Your "fillable" attribute in the model is empty. Make sure you put "status" in that array. Attributes that are not in this array cannot up modified.

Categories