XQuery - Problem with map merging - Execution xbase - xpath

I am very new in xquery and I have a problem, that I can't get solved.
I want to iterate a xml and save some entries in a map. So that I can merge the same keys with different values (StringValue1, StringValue2). At the end I want to return the complete map and save it to a file. Following you find my code. And I using xbase to execute these xquerys.
CODE
declare namespace functx = "http://www.functx.com";
(: Function should merge the values, if the map contains the key, else it should put the new entrie to the map.:)
declare function functx:pnMap($map as map(*), $key as xs:anyAtomicType, $value as item()*) as map(*) {
if(map:contains($map, $key)) then (map:merge(($map, map{$key:$value}), map{"duplicates":"combine"})) else map:merge((map{ $key: $value }, $map))
} ;
let $pnMap := map{}
for $x in doc('file:///D:/Software/BaseX932/basex/input/MyXML.xml')/PFA/Records/Entity
return functx:pnMap($pnMap, substring-before((substring-after(data($x/BigUnsortedStringField), 'Owner: ')), '
'), string-join(('Position=Owner | ', 'EntityID=', data($x/#id),' | ', 'SomeOtherNo=', data($x/IDNumberTypes/ID[#IDType="StringWhereIfindsomeOtherNumber"])), ''))
RESULT
map {
"Nick": "Position=Owner | EntityID=625115 | SomeOtherNo=7206512"
}
map {
"James": "Position=Owner | EntityID=1016624 | SomeOtherNo=9138056"
}
map {
"Nick": "Position=Owner | EntityID=1016625 | SomeOtherNo=9051648"
}
map {
"Pete": "Position=Owner | EntityID=1016626 | SomeOtherNo=9051636"
}
map {
"Jon": "Position=Owner | EntityID=1016675 | SomeOtherNo=9349667"
}
Expected Result 1
map {
"Nick": "Position=Owner | EntityID=625115 | SomeOtherNo=7206512, Position=Owner | EntityID=1016625 | SomeOtherNo=9051648"
"James": "Position=Owner | EntityID=1016624 | SomeOtherNo=9138056"
"Pete": "Position=Owner | EntityID=1016626 | SomeOtherNo=9051636"
"Jon": "Position=Owner | EntityID=1016675 | SomeOtherNo=9349667"
}
This is an abbreviated excerpt from the XML:
<Entity id="1016626">
<Status>Active</Status>
<IDNumberTypes>
<ID IDType="SomeOtherNo">
<IDValue>9051636</IDValue>
</ID>
</IDNumberTypes>
<BigUnsortedStringField>Some text
Owner: Pete
Sister: Magrit
Next Line text
more text
</BigUnsortedStringField>
</Entity>
<Entity>
....
</Entity>

I think you want
map:merge(
doc('file:///D:/Software/BaseX932/basex/input/MyXML.xml')/PFA/Records/Entity !
map:entry(
substring-before(substring-after(BigUnsortedStringField, 'Owner: '), '
'),
string-join(('Position=Owner', 'EntityID=' || #id, 'SomeOtherNo=' || IDNumberTypes/ID[#IDType="StringWhereIfindsomeOtherNumber"]), ' | ')
),
map { 'duplicates' : 'combine' }
)
but it is hard to write code without seeing the XML input.
As an alternative you could also try to use XQuery group by first on the data you want and then create the map of the result of the grouping:
map:merge(
for $entity in doc('file:///D:/Software/BaseX932/basex/input/MyXML.xml')/PFA/Records/Entity
group by $owner := substring-before(substring-after($entity/BigUnsortedStringField, 'Owner: '), '
')
return
map:entry($owner, string-join(
$entity!string-join(('Position=Owner', 'EntityID=' || #id, 'SomeOtherNo=' || IDNumberTypes/ID[#IDType="StringWhereIfindsomeOtherNumber"]), ' | '), ' , '))
)

Related

Eager loaded relationship giving wrong values

I have a Laravel model 'Delegates' with a list of students doing training.
I also have 2 other Models/tables:
honorifics - Mr, Ms, Miss, etc. and
Countries - all the countries in the world
My Delegates model has 2 methods to link to the relationship tables:
public function HonorificInfo()
{
return $this->hasOne(\App\Models\Honorific::class, 'ID', 'HonorificId');
}
and
public function NationalityInfo()
{
return $this->hasOne(\App\Models\Country::class, 'id', 'Nationality');
}
My Delegates table has 2 records of relevance:
| id | HonorificId | FamilyName | ForeNames | Nationality |
| -- | ----------- | ---------- | --------- | ----------- |
| 16425 | NULL | FamilyName1 | ForeNames1 | NULL |
| 16426 | 1 | FamilyName1 | ForeNames1 | 133 |
My Controller has this query:
$delegates = Delegate::with(['HonorificInfo.honorific', 'NationalityInfo.CountryName'])->where('ForeNames', 'Forenames1')->where('FamilyName', 'FamilyName1')->withTrashed()->get();
which gets the 2 records with the relationship tables.
debugging the data shows this:
$delegates=[{"id":16425,"HonorificId":null,"FamilyName":"FamilyName1","ForeNames":"Forename1","honorific_info":{"id":1,"honorific":"Mr"},"nationality_info":null},{"id":16426,"HonorificId":"1","FamilyName":"FamilyName1","ForeNames":"Forename1", "honorific_info":null,"nationality_info":{"id":133,"CountryName":"Malaysia"}}]
This is wrong. For record 16425, HonorificId is null so honorific_info should also be null - it is returning "Mr".
For record 16426, HonorificId is 1 so honorific_info should be Mr but the honorific_info relation data is null!
In my blade I have some debugging info which looks like this:
\Log::debug('delegates.edit2Dupes(): ' . $delegates[0]->id . ' = ' . $delegates[0]->HonorificId . ' = ' . $delegates[0]->HonorificInfo);
\Log::debug('delegates.edit2Dupes(): ' . $delegates[1]->id . ' = ' . $delegates[1]->HonorificId . ' = ' . $delegates[1]->HonorificInfo);
\Log::debug('delegates.edit2Dupes(): ' . $delegates[0]->id . ' = ' . $delegates[0]->Nationality . ' = ' . $delegates[0]->NationalityInfo);
\Log::debug('delegates.edit2Dupes(): ' . $delegates[1]->id . ' = ' . $delegates[1]->Nationality . ' = ' . $delegates[1]->NationalityInfo);
The debug info looks like this:
[2022-07-31 09:25:32] local.DEBUG: delegates.edit2Dupes(): 16425 = = {"id":1,"honorific":"Mr"}
[2022-07-31 09:25:32] local.DEBUG: delegates.edit2Dupes(): 16426 = 1 =
[2022-07-31 09:25:32] local.DEBUG: delegates.edit2Dupes(): 16425 = =
[2022-07-31 09:25:32] local.DEBUG: delegates.edit2Dupes(): 16426 = 133 = {"id":133,"CountryName":"Malaysia"}
The Nationality info works perfectly - the first record has null Nationality & the 2nd record has Nationality of Malaysian.
I can't even see how this is possible! The tables are in SQL Server and they all have the correct primary keys & foreign keys. This is actually simplified and there are a lot more relationships in addition to Nationality such as country of birth, present country of abode, etc. Everything works perfectly apart from this Honorific and Honorific works fine in other parts of my code.

jq: recursion -> nested arrays

How can I parse this json structure with jq? It should loop over leafs (projects and groups) recursively.
My use case is: create project and groups in VCS with CLI. Group can have multiple projects, group can be empty, projects must have parent group created in advance.
Similar analogy would be:
group = folder
project = file
path = absolute path in format /root-groups/nested-groups-level-1/nested-groups-level-2/nested-groups-level-N
Thanks
{
"structure":[
{
"name":"rootgroup1",
"type":"group",
"nested":[
{
"name":"nestedproject1",
"type":"project"
},
{
"name":"nestedgroup1",
"type":"group",
"nested":[
{
"name":"nestednestedproject2",
"type":"project"
}
]
}
]
},
{
"name":"rootproject1",
"type":"project"
},
{
"name":"rootgroup2",
"type":"group",
"nested": []
}
]
}
Expected output:
"rootgroup1","group",""
"nestedproject1","project","rootgroup1"
"nestedgroup1","group","rootgroup1"
"nestednestedproject2","group","rootgroup1/nestedgroup1"
"rootproject1","project",""
"rootgroup2","group",""
Try:
jq -r '.structure[] | .. | "\(.name?) \(.type?)"'
Still not sure, how create a parent path.
The following implements a solution to the problem as I understand it:
# $prefix is an array interpreted as the prefix
def details($prefix):
def out:
select(has("name") and has("type")) | [.name, .type, "/" + ($prefix|join("/"))];
out,
if (.nested | (. and length>0))
then .name as $n | .nested[] | details($prefix + [$n])
else empty
end;
.structure[]
| details([])
| #csv
Given your sample input, the output would be:
"rootgroup1","group","/"
"nestedproject1","project","/rootgroup1"
"nestedgroup1","group","/rootgroup1"
"nestednestedproject2","project","/rootgroup1/nestedgroup1"
"rootproject1","project","/"
"rootgroup2","group","/"
This differs in some respects from the sample output, but hopefully you can take it from here.

Is it possible to groupBy (month) and sum (each column) in table

+---------+--------+---------+---------+
| date | type_a | type_b | type_zzz|
+---------+--------+---------+---------+
|01-01-18 | 12 | 10 | 1 |
|02-01-18 | 2 | 5 | 1 |
|03-01-18 | 7 | 2 | 2 |
|01-02-18 | 13 | 6 | 55 |
|02-02-18 | 22 | 33 | 5 |
+---------+--------+---------+---------+
Hi,
In above example, I would like to know if it's possible to groupBy month and sum each column when getting results in Laravel (tables are dynamic so there are no models for them and also some tables don't have column 'type_a' other don't have 'type_zzz' etc...).
What I'm looking to get from above table is something like this:
"01" =>
'type_a' : '21',
'type_b' : '17',
'type_zzz': '4'
"02" =>
'type_a' : '35',
'type_b' : '39',
'type_zzz': '60'
I'm using following code to group it by month but I'm not able to find solution to return sum by each column:
DB::table($id)->get()->groupBy(function($date) {
return Carbon::parse($date->repdate)->format('m');;
});
If I understand your question correctly, you can either group and sum the values using an SQL query:
$grouped = DB::table('table_name')
->selectRaw('
SUM(type_a) AS type_a,
SUM(type_b) AS type_b,
SUM(type_z) AS type_z
')
->groupByRaw('MONTH(date)')
->get();
Or if you don't want to have to specify the column names in each query, you can use groupBy, array_column, and array_sum on your collection:
$grouped = DB::table('table_name')
->get()
->groupBy(function ($item) {
return Carbon::parse($item->date)->format('m');
})
->map(function ($group) {
$group = $group->toArray();
$summed = [];
$columns = array_keys($group[0]);
array_shift($columns);
foreach ($columns as $column) {
$summed[$column] = array_sum(array_column($group, $column));
}
return $summed;
});

How can I filter a query using laravel relationships

I have a table of items that contain info of the items. Plus, I have 3 other tables for some characteristics that could have more than one.
Follows an example:
table items
-----------------------
| id | price | stock |
-----------------------
| 1 | 19 | 99 |
-----------------------
table tallas
-----------------------------
| id | item_id| description |
-----------------------------
| 1 | 1 | large |
-----------------------------
table colors
-----------------------------
| id | item_id| description |
-----------------------------
| 1 | 1 | blue |
-----------------------------
table materials
-----------------------------
| id | item_id| description |
-----------------------------
| 1 | 1 | cotton |
-----------------------------
I want to know if there is a way where I can filter an item passing the item_id to the tallas relationship without using join (for example).
My model looks like this:
<?php
class Item extends Eloquent{
use Conner\Tagging\TaggableTrait;
public function tallas()
{
return $this->hasMany('Talla','item_id');
}
public function colores()
{
return $this->hasMany('Color','item_id');
}
public function materiales()
{
return $this->hasMany('Material','item_id');
}
public function imagenes()
{
return $this->hasMany('ItemImage','item_id');
}
}
And I have tried this:
$items = Item::with('imagenes')
->with(array('tallas' => function($query) use($dataFilter) {
$query->where('id','=',$dataFilter['filter-size']);
}));
But this return all the items and filter the tallas , using the example tables if i look for an item small it will return something like this.
[item]{
id:1,
price:19,
stock:99,
tallas:
[]...
colores:
[]...
materiales:
[]...
}
It should not return any item, any help?
EDITED
i forget to mention i'm using laravel 4.2
If I understand you question correctly I think you want whereHas e.g.
$items = Item::with('imagenes')
->whereHas('tallas', function ($query) use ($dataFilter) {
$query->where('id', '=', $dataFilter['filter-size']);
});
https://laravel.com/docs/4.2/eloquent#querying-relations
Hope this helps!

Cakephp 3: belongsToMany contain or matching condition?

Piece of my database looks like database part
Categories use tree behavior.
How can i get a manufacturer's (Producers) Products for current Category?
I tried contain and matching, but i received duplicated data or Producers names without related Products.
EDIT:
$query = $this->Producers->find()->matching('Products.Categories',
function ($q) {
return $q->where(['Categories.id' => 18]);
}
);
Results:
Producent: Canon
-------------------------------------------
| ID | Name | Barcode |
-------------------------------------------
| 1 | EOS 1000D | |
-------------------------------------------
| 18 | Camera | |
-------------------------------------------
| 23 | 18 | |
-------------------------------------------
First row (id = 1) it's what i need.
Now i have to remove from results:
second row (id = 18) this is Category id from table Categories,
thrid row (id = 23) - from Products_Categories table.
Done. There is working query:
$query = $this->Producers->find()
->select(['Producers.id','Producers.name', 'Products.id', 'Products.name'])
->matching(
'Products.Categories', function ($q) use ($categoryId){
return $q->where(['Categories.id' => $categoryId]);
}
);

Resources