Play 2.0 Complex join query how to parse (Anorm ) - mysql

I am writing website using play 2.0 framework. And I have a problem when parsing results.
This request to mysql db gets all the links(can be several per episode) added to the database per episode together with all the information about episode and anime.
def lastReleasedLink(limit:Long=5):List[(((Episode,Anime),Link),Genre)] = {
DB.withConnection { implicit c =>
SQL(
"""
select * from yas_episodes as a
inner join anime as b on a.ep_anime_id=b.id
left outer join yas_links as c on a.ep_id=c.ep_id
LEFT JOIN yas_animes_genres AS d ON a.ep_anime_id = d.ag_anime_id
INNER JOIN yas_genres AS e ON e.g_id = d.ag_genre_id
where c.ep_id IS NOT NULL group by c.ep_id order by c.date desc limit {limit}
""").on('limit ->limit)as(Episode.simple~Anime.simple~Link.simple~Genre.simple map{
case episode~anime~link~genre => episode -> anime -> link -> Genre
} *)
}
}
The return value is type of List[(((Episode,Anime),Link),Genre)]
but how can I form output to the list of
let say List[episode,anime,Seq[links]] or List[episode,anime,Seq[Genres],Seq[links]] don't know where to put genres.
You can imagine that when you have two links per one episode information from table anime and yas_episodes will be copied for every row. So I need somehow stack them together(group) by episode record. Then it will be possible to iterate list and access to all objects.
As you can see, in the request there is many-to-many relation of anime with genres.
I have no idea how can I put all together to one list to be able to access it in view. Should Genre be part of Anime model?

It seems that the preferred way to achieve this is using the Scala collection API, see this post by Guillaume Bort.
In your case, I think you could do something like
lastReleasedLink groupBy { case (((e, a), l), g) => (e, a) }
to group by (Episode, Anime). Generally speaking, those manipulations are probably a little easier if you change your function to return a List[(Episode, Anime, Link, Genre)], i.e.
case episode~anime~link~genre => (episode, anime, link, genre)
then you could achieve the same with this code:
lastReleasedLink groupBy ((_._1, _._2))

Related

Return only matched elements in MongoDB

I'm trying to "translate" a query from MySQL,
SELECT a.Nome, a.PosicaoPrimaria, a.PosicaoSecundaria
FROM Atleta AS a INNER JOIN Equipa AS e ON a.Equipa_idEquipa = e.idEquipa
WHERE e.Localidade = 'Braga' AND a.PosicaoSecundaria != ''
ORDER BY a.PosicaoSecundaria;
to a MongoDB query. So far, so good. I've searched to try and understand how I can manage to do what I want, but I have come to a halt.
So far, this is what I have as a MongoDB query,
db.Atleta.aggregate([
{$lookup:
{from:"Equipa",
let: {e:"$Equipa_idEquipa", ps:"$PosicaoSecundaria"},
pipeline:[
{$match:
{$expr:
{$and: [ {$eq:["$idEquipa", "$$e"]},
{$ne:[null, "$$ps"]},
{$eq:["$Localidade", "Braga"]} ] } } }],
as:"Query" }},
{$project:{Query:1, Nome:1, PosicaoPrimaria:1, PosicaoSecundaria:1, _id:0}} ]).pretty()
This gives me the results I want in the players I want to be returned, but it also returns all the other players, who 'don't fit the bill' on the query. See image below.
Query results
What I really need, is to filter the results to only show the players who have the "Query" array as not empty. Is there a way that can be done?

How to get ordered results from couchbase

I have in my bucket a document containing a list of ID (childList).
I would like to query over this list and keep the result ordered like in my JSON. My query is like (using java SDK) :
String query = new StringBuilder().append("SELECT B.name, META(B).id as id ")
.append("FROM" + bucket.name() + "A ")
.append("USE KEYS $id ")
.append("JOIN" + bucket.name() + "B ON KEYS ARRAY i FOR i IN A.childList end;").toString();
This query will return rows that I will transform into my domain object and create a list like this :
n1qlQueryResult.allRows().forEach(n1qlQueryRow -> (add to return list ) ...);
The problem is the output order is important.
Any ideas?
Thank you.
here is a rough idea of a solution without N1QL, provided you always start from a single A document:
List<JsonDocument> listOfBs = bucket
.async()
.get(idOfA)
.flatMap(doc -> Observable.from(doc.content().getArray("childList")))
.concatMapEager(id -> bucket.async().get(id))
.toList()
.toBlocking().first();
You might want another map before the toList to extract the name and id, or to perform your domain object transformation even maybe...
The steps are:
use the async API
get the A document
extract the list of children and stream these ids
asynchronously fetch each child document and stream them but keeping them in original order
collect all into a List<JsonDocument>
block until the list is ready and return that List.

Complicated Laravel relationship to generate view

I have Orders which contain any number of items stored in the items table (so a belongsToMany relationship between the two). The items are also categorized under itemtypes. When creating or editing an order I would like to load all items, categorized by itemtype, whether or not that order has any of the items. I was able to pull that up generically using the following:
$itemtypes = \App\Itemtype::with('items')
->orderBy('id','asc')
->get();
Then I loop through:
#foreach( $itemtypes as $itemtype )
{{$itemtype->name}}
#foreach( $itemtype->items as $item )
{{$item->name}}
#endforeach
#endforeach
This gives me something like:
NICU Items
- Baby Blanket
- Beaded Baby Cuddler
Miscellaneous Items
- Fitted Sheet
- Microfiber Towel
However, when I'm accessing a specific order which has records in item_order I want to display the saved quantities (stored in the pivot table). I know one way would be to add records for all items to item_order for every order created but that seems rather inefficient.
Item.php
public function orders() {
return $this->belongsToMany('App\Order', 'item_order', 'item_id', 'order_id') -> withPivot('id','quantity','createdby_user_id','weight','cost_billed', 'calc_by_weight', 'track_units');
}
Order.php
public function items() {
return $this -> belongsToMany('App\Item', 'item_order', 'order_id', 'item_id') -> withPivot('id','quantity','quantity_received','quantity_delivered','notes', 'createdby_user_id', 'weight', 'cost_billed', 'calc_by_weight', 'track_units');
}
UPDATE
I'm on the trail to a solution. I'm converting the collection to an array, loaded up with all items, modifying the array as needed, then using array_merge to replace the items that have quantities already in item_order.
This all works great - the only issue I'm having now is that when I load the order with it's items, items have an itemtype - a categorization and I'd like to group them by that. I'm not sure how to add a groupby to a relationship. If I figure it all out i'll post the full answer then.

Returning nested JSON from many to many joined table from PostgreSQL to node.js

can anyone help me with querying many to many relation tables in postgres?
i have tables:
> 1.exercise(id,name)
> 2.tag(id,label)
> 3.tag_in_exercise(id,exercise_id,tag_id)
let say, that we have one exercise bonded with two tags via tag_in_exercise
when using query :
select e.id,t.label from exercise e
left join tag_in_exercise te on e.id=te.exercise_id
left join tag t on te.tag_id=t.id
i will receive json
[ { id: 1,
label: 'basic1' },
{ id: 1,
label: 'basic2' }]
but i want to receive it as nested json
[ { id: 1,
tags:[ {'basic1'},{'basic2'} ]
}]
is it possible to get that by using standart postgresql queries or i need to use some ORM?
or if exists another solution please let me know,
thanks
PostgreSQL does not return the JavaScript object you have posted. Your node driver is converting an array of arrays returned by PostgreSQL, which the driver is converting to JavaScript objects.
However, you can have PostgreSQL return a structure which I suspect will be converted how you wish by using array_agg.
Try this:
SELECT e.id,array_agg(t.label) AS label
FROM exercise e
LEFT JOIN tag_in_exercise te on e.id=te.exercise_id
LEFT JOIN tag t on te.tag_id=t.id
GROUP BY e.id;
You will get a raw PostgreSQL result in the structure you want, which hopefully the driver will translate as you intend:
id | label
----+-----------------
1 | {basic1,basic2}
2 | {NULL}

Uitableview, json and detail tableview

I am asking a very simple question for someone who has encountered this kind of problem, please don't mark it down because there are many approaches to a solution.
I have a database which has cities and town, cities has many town, therefore, using one query displays many cities to correspond to the town. The result is as follows from mysql;
{City - town 1, town2, town 3} therefore if I want to display both the town and cities, I will end up with {city-town1, city-town2, city-town3}
I want to be able to compile all towns under a city, so that I can eventually use this source of array for my drilldown table, i.e on the first table; I want a list of non-repeating cities, on detail table, a list of all towns under that city. I only want to use one table and make the array dynamic such that I can add cities and towns without any problems (I have seen examples proposing different tables for different arrays)
I used this for- loop to iterate through mysql result
for (int i=0; i<json.count; i++)
{
ids= [[json objectAtIndex:i] objectForKey:#"Id"];
cityName = [[json objectAtIndex:i] objectForKey:#"cityName"];
townName = [[json objectAtIndex:i] objectForKey:#"townName"];
}
This gives me a list of cities but they are repeating;
I have been thinking about different approaches;
1)use #distinctunion- (Key-Value Coding)
2)use two jsons (one for city and another for towns) -compile arrays under each then join them using common id
3)use an iteration, iterate as shown above, but also search for similar cityNames and group towns under cities
Has anyone encountered a similar situation? what did you do? could you give an example if possible please
This is JSON Result for NSMutable Array of the above iteration
2013-09-18 07:50:52.025 JSONDATA[7119:11603] (
Bath,
"Bath, Somerset"
)
2013-09-18 07:50:52.035 JSONDATA[7119:11603] (
Bath,
"Bath, Somerset"
)
2013-09-18 07:50:52.035 JSONDATA[7119:11603] (
Bath,
Keynsham
)
2013-09-18 07:50:52.035 JSONDATA[7119:11603] (
Bath,
Keynsham
)