Laravel / Mongodb - How to get data based on array object key - php

I have this array of objects in mongodb database:
"matching_competitors": [
{
"id_competitor": "19",
"domain": "",
"id_product_competitor": 35035,
"url_product_competior": "https://www.bogas.ro/rochie-dama-scurta-catifea-neagra-antonietta-bogas/?utm_source=googlemerchantcenter&utm_medium=cpc&utm_campaign=direct_link"
}
]
Now, I want to get data where id_competitor is equal to 19. What I am doing is :
$get_product = DB::connection('mongodb')->collection( 'products_' . $id_project );
// another condtion.....
$get_product->orWhere( 'matching_competitors', '$elemMatch', [ 'id_competitor' => $match_to] );
Here the $match_to is contain id_competitor value.
But I can't get any result.

Related

Laravel / Mongodb - How to build query where count array of objects equal to total numher of competitor

I have this array (matching_competitors) of objects in the mongodb server:
"matching_competitors": [
{
"id_competitor": "21",
"domain": "",
"id_product_competitor": 224731,
"url_product_competior": "https://www.librarie.net/p/224731/nia=1693"
},
{
"id_competitor": "21",
"domain": "",
"id_product_competitor": 282868,
"url_product_competior": "https://www.librarie.net/p/282868/nia=1693"
}
]
and I have 3 competitors in competitors table (mysql)
Now, I need to build a query where -> size of matchig_competitors (mongodb) should equal to total competitor (mysql)
I can not get any idea how to build this query.
My current query:
$get_product = DB::connection('mongodb')->collection( 'products_' . $get_project_id->id_project )->Where( 'matching_competitors', $total_competitor )->paginate(6);
You can do it like this.
$competitorCount = DB::table('competitors')->count();
$get_product = DB::connection('mongodb')
->collection('products_' . $get_project_id->id_project)
->whereRaw(['$expr' => ['$eq' => ['$size' => '$matching_competitors'], $competitorCount]])
->paginate(6);

Retrieve array object in a table from another table data id using a where clue in laravel

Question: I have two tables how to fetch a customer's data using order's table user_id
"order": [
{
"id": 1,
"user_id": 4
},
{
"id": 2,
"user_id": 5
}
],
"customers": [
{
"id": 5,
"name": "Mohamed Raazi",
"phone": "777",
}
],
Following code will return only the last object of an array, i need to display all the objects from user table using a where condition in customers table
for ($x=0; $x<count($orders); $x++){
$customer = User::where('id',$orders[$x]->user_id)->get();
}
I would use the ::whereIn-method where you can provide an array of IDs to and get all the users with the provided IDs.
First you would have to reformat the $orders array that you have so that it contains only user IDs. I am guessing that you are using Eloquent to fetch the orders, then you can use the pluck-function in your Eloquent-statement:
$userIds = Order::where('statement', true)->pluck('user_id')->toArray();
Please note that the where-statement is not real, I just want to illustrate how you can call the pluck-method.
Another alternative is that you use the map function on the $orders-collection and return only user IDs:
$userIds = $orders->map(function ($order) {
return $order->user_id;
});
Once you have your user IDs in an array/collection you can use it in the whereIn-statement:
$users = Users::whereIn('id', $userIds)->get();
Then this would give you all the users that that are connected to the orders you have in your order-collection.

Parse JSON without relying on order

I have this JSON, I'm parsing. I can retrieve all the values of field_data in order in PHP, but I need to traverse and get the values I wan't by specifying the field name, without concern for order:
JSON
{
created_time: "2018-05-14T16:11:02+0000",
id: "555555555555",
field_data: [
{
name: "bedrooms_interested_in?",
values: [
"2"
]
},
{
name: "When_are_you_looking?",
values: [
"January 1s 2019"
]
},
{
name: "email",
values: [
"xxxx#domain.com"
]
},
{
name: "full_name",
values: [
"John Michael"
]
},
{
name: "phone_number",
values: [
"+15555555555"
]
}
]
}
PHP
This is grabbing the last 3 fields. I'm currently able to pull the fields_data in order like this, but how could I grab the value fields I want by specifying the name field I'm looking for?
$data = json_decode($response, true);
// var_dump($data);
file_put_contents('dump.txt', $response);
$lead_email = $data['field_data'][2]['values'][0];
$lead_fullname = $data['field_data'][3]['values'][0];
$lead_phone = $data['field_data'][4]['values'][0];
You can use array_column to re-index an array by a given column, which will give you easier and more reliable access to the data:
$data['field_data'] = array_column($data['field_data'], null, 'name');
This allows you to access fields by name instead of their numeric index, e.g.
echo $data['field_data']['email']['values'][0];
// xxxx#domain.com
See https://eval.in/1003874 for a full example
(Note, I added some quotes to your JSON property names, since they were missing in the question. I assume that's a formatting issue, since this wouldn't work at all otherwise)

Laravel Validator Facade - Validate size based on another field value

I have a form where the user must define the number of items to save and when you submit the form and parse it to JSON it looks like this:
{
"numItems": 3,
"items": [
"1" : {"A": "Foo", "B:"bar"},
"2" : {"A": "Foo", "B:"bar"},
"3" : {"A": "Foo", "B:"bar"},
],
}
And I want to validate that the number of items inside items matches with the value of numItems.
I've tried with:
$aValidations = [
"numItems" => "required|int|max:10",
"items" => "required|array|size:numItems",
]
But even if the number of item matches the numItems value I get this:
{
"message": "The given data was invalid.",
"errors": {
"items": ["The items must contain numItems items."]
}
}
How can I achieve this?
One way would be to write a custom validator (you can put this in your AppServiceProvider#boot method). Something like (not tested/pseudocode):
Validator::extend('coolValidatorName', function ($attribute, $value, $parameters, $validator) {
$data = $validator->getData();
return $data[$parameters[0]] == count($value)
});
https://laravel.com/docs/5.5/validation#custom-validation-rules
The size rule accepts a numeric value which it then compares against the size of the input[1], it does not accept a field reference.
If you would like to compare against the value taken from another field you will need to pass in that field value yourself, e.g:
$aValidations = [
"numItems" => "required|int|max:10",
"items" => "required|array|size:" . $data->get('numItems'),
]
note: assumption has been made that you have decoded your json and then created a collection.
e.g:
$json = '{"numItems":4,"items":[{"a":"foo","b":"bar"},{"a":"foo","b":"bar"},{"a":"foo","b":"bar"}]}';
$data = collect((array) json_decode($json));
$aValidations = [
"numItems" => "required|int|max:10",
"items" => "required|array|size:" . $data->get('numItems'),
];
[1] For a string it compares the number of characters, for an integer it compares the values as is, for an array it compares the count of top level elements and for a file it compares the file size.

PHP + MongoDB - Fetch entry from array inside collection with $elemMatch not working

I have the following object:
{
users: {
_id: "users",
entries:
[
{
_id: 1,
username: "taxicala",
password: "password"
},
{
_id: 2,
username: "guest",
password: "guest"
}
]
}
}
And I want to select only one user that is within the "entries" array. I am trying the following:
$entry = $this->_users->find(
array('entries' =>
array('$elemMatch' =>
array('username' => 'taxicala')
)
)
);
The result I get is an empty object:
{ }
I could not find any clue over Google or here about this. Am I doing something wrong? Am I missing something? or is '$elemMatch' not supported by PHP?
Thanks!
$elemMatch is supported but as far as you document goes, you entries are inside the user object. So at least in your query you have to put array('users.entries' => ...). Also I do not see why do you need to use $elemMatch.
db.coll.find({"users.entries.username" : "taxacala"}) outputs the documents with username "taxacala".

Categories