How to join results from with operator in Laravel? - laravel

I use query builder for execution inquiries to db like as:
$result = Order::with("product", "images");
As result I get response with two nested objects inside:
{["product" : [{}], "images" : [{}]]}
How can I join these two objects to one, that to get the following response:
{"title" : "Product name", "price" : 3, "images" :{}, "order" : {} }

You should use nested eager loading here:
Order::with('products.images')->first();
If you want to get an array or JSON instead of collection, use toArray() or toJson() methods on collection.

Related

Can I directly get a nested list in my Doctrine result?

Sorry if the question is poorly phrased, I couldn't come up with a good way of describing my issue.
So basically, I'm using the Doctrine query builder to try and a list of training sessions from my Session entity. For each session, I need to fetch basic properties such as the name and date, but I also need to fetch the list of participants. There is a one-to-many relation between the entities Session and Participant, as there may be several participants to a given session. I would simply need a list of these participants, nested in each item of the list of sessions. Something like this:
[
{
"session_name": "name1",
"session_date": "date1",
...
"participants": [
{
"participant_name": "john1",
...
},
{
"participant_name": "john2",
...
},
...
],
},
{
"session_name": "name2",
"session_date": "date2",
...
"participants": [
{
"participant_name": "john3",
...
},
{
"participant_name": "john4",
...
},
...
],
},
...
]
This seems to me like it should be quite basic, but for the life of me I cannot get it to work with JOINs, subqueries, etc. The closest I got was this error, which does imply I'm trying to get a nested array (but it won't let me):
SQLSTATE[21000]: Cardinality violation: 1242 Subquery returns more than 1 row
I had this error running this code:
$query = $this->createQueryBuilder('s')
->select('
s.name,
s.date,
(SELECT p.nom FROM '.Participant::class.' p WHERE p.session = s.id) participants
')
->getQuery()->getArrayResult();
I know I could just fetch my sessions, then loop through them and fetch their participants with another DQL query, but obviously that doesn't seem like the proper way to do it. Is there a better way?
You can directly do a leftJoin on your QueryBuilder :
$queryResult = $this->createQueryBuilder('s')
// After that next line, you can reference participants as 'p'
->leftJoin('s.participants', 'p')
// If you intend to loop on the result, to avoid the N+1 problem, add this line :
->addSelect('p')
->getQuery()
->getResult()
;

why this code works and eloquent create the subdocument if it is not exists?

suppose I have a collection with name ParrentObj and a corresponding Eloquent class named ParrentObj:
[//ParentObj eloquent objects
{
"_id":ObjectId("5e11ae242cb48f79afcd4b07"),
"Code":"a"
"Children":[
//children eloquent objects
{
"Code":"a-a",
"GrandChildren":[
//GrandChildren eloquent objects
{
"Code":"a-a-a"
},
{
"Code":"a-a-b"
}
]
},
{
"Code":"a-b",
"GrandChildren":[
]
}
],
},
{
"_id":ObjectId("5e11b125e1f94bccca6784e9"),
"Code":"b"
"Children":[
]
}]
I amazed how this line of code works properly because all evidence shows against it:
$result = ParrentObj::find('5e11ae242cb48f79afcd4b07')->where('Children.Code', 'a-a')
->whereNotIn('Children.GrandChildren.Code',['a-a-a'])
->push('Children.$.GrandChildren', $arr);//results: no effect on db
$result = ParrentObj::find('5e11ae242cb48f79afcd4b07')->where('Children.Code', 'a-a')
->whereNotIn('Children.GrandChildren.Code',['a-a-c'])
->push('Children.$.GrandChildren', $arr);//results:add a GrandChildren subdocument under the a-a Children
"ParrenObj" is an Eloquent Object that has a embedsMany relation On the Children field.
"Children" is also an eloquent object that has an "embeds many" relation on the GrandChildren field. (to 0 or n "GrandChildren" eloquent object(s))
as I know the result of the find is an eloquent or collection and with combination with where the result will be a query builder. when I try to get the result of this:
$result = ParrentObj::find($id)->where('Children.Code', "a-a")->first()
the result was a ParrentObj (eloquent object). and as I anticipate the Children field has two members (not one). How eloquent determine that ->push('Children.$.GrandChildren', $arr); should be applied on which Children?
It does not work for this case:
$result = ParrentObj::find('5e11ae242cb48f79afcd4b07')->where('Children.Code', 'a-b')
->whereNotIn('Children.GrandChildren.Code',['a-a-a'])
->push('Children.$.GrandChildren', $arr);
expected results:
add a GrandChildren with code a-a-a subdocument under the a-b Children
actual result:
does not add any GrandChildren under a-b because whereNotIn matched a GrandChildren with same Code but in different Children

Is it possible to retrieve an object in an array that matches my query using elasticsearch?

Given a document like this:
{
"id": "12345",
"elements": [
{
"type": "configure",
"time": 3000
}
]
}
Is it possible to query for documents with an object in the elements array that have a type of configure and then also retrieve that specific object in the array so that I can also get the time value associated with that element (In this case 3000)?
You can use nested inner_hits to retrieve details of the nested objects that match for a nested query. Note that elements will need to be mapped as a nested datatype field.

Apiary: Refer to multiple models in a body

It seems you can only refer to the model itself in an unmodified form from a payload/body section:
# Item [/]
+ Model
{ "name" : "an item" }
## GET
+ Response 200
[Item][]
Is there any way to return an array of the model or use the model as a field? I.e. something like
+ Response 200
{ "items" : [ [Item][], [Item][] ]}
This is not possible yet.
It should be available soon using Traits.

LINQ to SQL: Selecting a one-to-many relationship

I've got two tables (articles and tags) that have a one-to-many relationship.
I remember seeing somewhere that I can create nested objects/arrays/etc from that relationship. The output of which I would like in a format such as (in JSON format):
{1 : {
id : 1,
title : 'article title',
tags : ({
id : 16,
tagname : 'first tag'
},{
id : 23,
tagname : 'another tag'
})
}
I'm creating an internal knowledge base system with a list view similar to the front page of stack overflow (that's the way I'd like to display the tags).
How would I go about doing this? A subquery? Thanks.
If I understand your question correctly you're looking for the SelectMany function which lets you 'unroll' nested structures like yours. SelectMany is indeed executed in Query syntax by a sub-query:
IEnumerable<Tag> =
from article in Articles
from tag in article.Tags
select tag;
In method form:
IEnumerable<Tag> tags = Articles.SelectMany(a => a.Tags);

Resources