2016-06-29 3 views
0

ich eine Abfrage in CakePHP, die das Datenobjekt in der folgenden Struktur zurück:Ändern von Objekt der Struktur der Ergebnisse in CakePHP 3

[ 
    { 
    "join_id": 1, 
    "contract_id": 1, 
    "title": "Title", 
    "sales": 500, 
    "earnings": 50, 
    "publisher": "Publisher", 
    "end_date": "2016-11-15" 
    }, 
    { 
    "join_id": 2, 
    "contract_id": 1, 
    "title": "Title", 
    "sales": 500, 
    "earnings": 50, 
    "publisher": "Publisher", 
    "end_date": "2016-01-15" 
    }, 
    { 
    "join_id": 3, 
    "contract_id": 2, 
    "title": "Title", 
    "sales": 500, 
    "earnings": 50, 
    "publisher": "Publisher", 
    "end_date": "2016-05-15" 
    } 
] 

Was ich tun möchte, ist die Struktur zu ändern, so dass es durch aufgespalten contract_id und bestimmte Felder auf seine Kinder beziehen, werden berechnet, wie folgt aus:

[ 
    { 
    "contract_id": 1, 
    "end_date": "2016-11-15", 
    "joins": [ 
     { 
     "join_id": 1, 
     "title": "Title", 
     "sales": 500, 
     "earnings": 50, 
     "publisher": "Publisher", 
     "end_date": "2016-11-15" 
     }, 
     { 
     "join_id": 2, 
     "title": "Title", 
     "sales": 500, 
     "earnings": 50, 
     "publisher": "Publisher", 
     "end_date": "2016-01-15" 
     } 
    ] 
    }, 
    { 
    "contract_id": 2, 
    "end_date": "2016-05-15", 
    "joins": [ 
     { 
     "join_id": 3, 
     "title": "Title", 
     "sales": 500, 
     "earnings": 50, 
     "publisher": "Publisher", 
     "end_date": "2016-11-15" 
     } 
    ] 
    } 
] 

Zusammenfassend ich die Ergebnisse von contract_id gruppieren möchten und die neuesten end_date von allen seinen Kindern berechnen.

ich in der Lage gewesen verkleinern zu verwenden, um die Ergebnisse von contract_id wie so gruppieren zu erhalten:

$mapper = function ($contractstitle, $key, $mapReduce) { 
     $contract_id = $contractstitle->contract_id; 
     $mapReduce->emitIntermediate($contractstitle, $contract_id); 
    }; 

    $reducer = function ($contractstitle, $contract_id, $mapReduce) { 
     $mapReduce->emit($contractstitle, $contract_id); 
    }; 

    $query->mapReduce($mapper, $reducer); 

Aber ich kann nicht herausfinden, wie berechnete Felder, um es hinzuzufügen. Ich bin nicht sehr erfahren mit MapReduce - ich denke, ich müsste die Daten durchlaufen, um den größten Wert zu bekommen, aber ich bin mir nicht sicher, wie ich das machen soll.

Ich habe mir auch die formatResults Methode angesehen, aber ich bin mir nicht sicher, ob das das ist, was ich verwenden sollte.

Danke,

Kez

EDIT - BEANTRAGT INFORMATION:

ich die Ergebnisse Struktur in meiner ersten Frage vereinfacht, da ich eine Abfrage erstellen ziemlich viel Zeit damit verbracht, die dies nicht taten endlos mehrere Male ohne Grund Looping. Es wäre schön, die Abfrage in Contracts zu starten und ContractsTitles zu enthalten, aber das ORM scheint das einfach nicht zu mögen, daher schien es mir meine beste Option, die Ergebnisse neu zu strukturieren, sobald ich alle Informationen bekommen konnte, die ich brauche. Natürlich konnte ich einfach manuell durch die Ergebnisse iterieren und das Array erstellen, das ich möchte, aber ich glaube, dass es einen besseren Weg dafür geben muss.

Dies ist die grundlegende Struktur der Tabellen verwendet:

ContractsTitles hasOne Reversions 
ContractsTitles hasOne Publications 
ContractsTitles belongsTo Contracts 
ContractsTitles belongsTo Titles 
ContractsTitles hasMany Royalties 

Und dies ist der Code in das Modell für die Abfrage:

$subQuery = $this->Contracts->Royalties 
    ->find() 
    ->contain(['Contracts']) 
    ->where(['Contracts.publisher_id' => $options['publisher_id']]); 

$subQuery 
    ->select(['contract_id' => 'Royalties.contract_id','title_id' => 'Royalties.title_id','sold' => $subQuery->func()->sum("sold"), 'earned' => $subQuery->func()->sum("earned")]) 
    ->group(['Royalties.title_id','Royalties.contract_id']); 

$query = $this->Contracts->ContractsTitles 
    ->find() 
    ->select(['Contracts.id', 'Contracts.date', 'Titles.title', 'Reversions.date', 'Publications.date', 'sold' => 'r.sold', 'earned' => 'r.earned']) 
    ->where(['Contracts.publisher_id' => $options['publisher_id']]) 
    ->contain(['Contracts','Titles','Reversions','Publications']) 
    ->join([ 
    'table' => $subQuery, 
    'alias' => 'r', 
    'type' => 'LEFT', 
    'conditions' => ['r.contract_id = ContractsTitles.contract_id','r.title_id = ContractsTitles.title_id'] 
    ]) 
    ->order(['Contracts.date DESC, Publications.date DESC']); 
+0

Können Sie Ihre Tabellen Struktur und Modell Defination? –

+0

Hallo Haresh, ich habe meine Frage aktualisiert, aber ich bin mir nicht sicher, wie viel es helfen wird! – Kez

Antwort