I'm trying to get the certain categories (on pid 1) with DatabaseQueryProcessor, which works almost perfectly, but some of the categories are displayed multiple times on the output of the variable.
(I am using headless typo3 10: https://github.com/TYPO3-Initiatives/headless)
brandcategories = JSON
brandcategories {
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
as = brandcategories
selectFields = sys_category.uid,sys_category.title
table = sys_category
pidInList = 1
where = parent=13
where.insertData = 1
join = sys_category_record_mm on sys_category_record_mm.uid_local =
sys_category.uid
}
}
}
This gives me the following Output:
[
{ "data": { "uid": 14, "title": "Barlow Tyrie", "pid": 1, "t3ver_state": 0 } },
{ "data": { "uid": 14, "title": "Barlow Tyrie", "pid": 1, "t3ver_state": 0 } },
{ "data": { "uid": 16, "title": "Dedon", "pid": 1, "t3ver_state": 0 } },
{ "data": { "uid": 17, "title": "Manutti", "pid": 1, "t3ver_state": 0 } },
{ "data": { "uid": 17, "title": "Manutti", "pid": 1, "t3ver_state": 0 } },
{ "data": { "uid": 19, "title": "Extremis", "pid": 1, "t3ver_state": 0 } }
]
As you can see uid 14 is displayed twice, as well as Manutti.
It would be great, if someone could tell me, how i can filter this, so I get every ID just once. Thanks!
In general you can limit the results of queries like this with two different options:
by usage of the mysql-Expression DISTINCT, I've no experience though if this can be used in TypoScript like selectFields = DISTINCT sys_category.uid,sys_category.title.
On this page is written
There is no support for DISTINCT, a ->groupBy() has to be used instead.
I'm not sure if that is applicable for your TypoScript-problem too.
by grouping the results with groupBy in TypoScript:
groupBy = sys_category.uid
A general explanation about both methods can be found here, the explanation is only related to MySQL and not to TypoScript.
Furthermore you could add more constraints to the join, so that the options above are not required.
Related
I'm very new to mongodb. I'm trying to do an aggregation pipeline for lookup kinda like SQL left join. Given the following document's schema:
Mongo playground: https://mongoplayground.net/p/yAIwH5V2yv8
Characters:
{
"_id": 1,
"account_id": 1,
"world_id": 0,
"name": "hello"
}
Inventories:
{
"_id": 7,
"character_id": 2,
"type": "EQUIPPED"
}
Items:
{
"_id": 1,
"inventory_id": 7
}
I want to query for characters and look up inventories as well as items in inventories. I was able to achieve this however I would like to separate the inventories field in characters result document.
Current result:
{
"_id": 2,
"account_id": 1,
"world_id": 0,
"name": "hello",
"inventories: [
{
"_id": 1,
"character_id": "2",
"type": "EQUIPPED",
"items: [...]
}
]
}
What I want is based on the type of inventory I want it to be a separate field of the resulted character document something like this:
{
"_id": 2,
"account_id": 1,
"world_id": 0,
"name": "hello",
"equippedInventory: {
"_id": 1,
"character_id": "2",
"type": "EQUIPPED",
"items: [...]
},
"equipInventory: {
"_id": 2,
"character_id": "2",
"type": "EQUIP",
"items: [...]
},
}
Also, is my pipeline the best way to achieve this?
Let's say I have a column with this jsonb data :
{
"indicators": [
{
"year": 2019,
"indicatorsByYear": [
{
"value": 3120,
"code": "Nb_h"
},
{
"value": 18,
"code": "S_ppa"
},
{
"value": 95,
"code": "T_occ"
}
]
},
{
"year": 2020,
"indicatorsByYear": [
{
"value": 300,
"code": "Nb_h"
},
{
"value": 18,
"code": "S_ppa"
},
{
"value": 55,
"code": "T_occ"
}
]
}
],
"dataProvidedByUser": false
}
The idea is to migrate this column to a simplified object like this :
{
"indicatorsByYear": {
"2019": [
{
"value": 3120,
"code": "Nb_h"
},
{
"value": 18,
"code": "S_ppa"
},
{
"value": 95,
"code": "T_occ"
}
],
"2020": [
{
"value": 300,
"code": "Nb_h"
},
{
"value": 18,
"code": "S_ppa"
},
{
"value": 55,
"code": "T_occ"
}
]
},
"dataProvidedByUser": false
}
How can I transform the indicators array to map object with year as key and indicatorsByYear as value.
For info, the maximum number of years that I can have is 11 years (from 2010 to 2020), some columns have all the years others only some.
My attempts with something like that without success
update site
SET data = data
|| jsonb_build_object('indicatorsByYear',
jsonb_build_object(
data -> 'indicators' ->> 'year',
data -> 'indicators' ->> 'indicatorsByYear'
))
Any help would be very much appreciated! Thanks in advance.
data -> 'indicators' is an array, whose elements you need to consider individually and then aggregate back together into an object. You can use jsonb_array_elements and jsonb_object_agg respectively for this.
Also, you'll want to remove the old indicators key from the data column.
UPDATE site
SET data = jsonb_set(
data - 'indicators',
'{indicatorsByYear}',
(
SELECT jsonb_object_agg(el ->> 'year', el -> 'indicatorsByYear')
FROM jsonb_array_elements(data -> 'indicators') el
)
);
I'm using loopback 3 to build a backend with mongoDB.
So i have 2 models: Object and Attachment. Object have a relation Embeds2Many to Attachment.
Objects look like that in mongoDB
[
{
"fieldA": "valueA1",
"attachments": [
{
"id": 1,
"url": "abc.com/image1"
},
{
"id": 2,
"url": "abc.com/image2"
}
]
},
{
"fieldA": "valueA2",
"attachments": [
{
"id": 4,
"url": "abc.com/image4"
},
{
"id": 5,
"url": "abc.com/image5"
}
]
}
]
The question is: how can i get Objects with attachments.id=4 over the RestAPI?
I have try with the where and include filter. But it didn't work. It look like, that this function is not implemented in loopback3, right?
I have found the solution. It only works on Mongodb, Cloudant and Memory database.
{
"filter": {
"where": {
"attachments.id": 4
}
}
}
I have an problem to send a REST query to featherjs with the $like operator.
Table:
ID Textfield
1 andreas
Query get
localhost:3030/table?textfield[$like]=andreas
returs the row
Query get
localhost:3030/table?textfield[$like]=andrea
localhost:3030/table?textfield[$like]=andrea%
localhost:3030/table?textfield[$like]=andrea*
all this query return 0 rows
Model is Sequelize -> SQL Server
Whats wrong with the url.
I setup your example with the addition of a createdAt and updatedAt field in your test table.
I used a feathersjs Model of Sequelize -> MySQL
Table:
ID Textfield
1 andreas
I used postman to test your GET queries:
localhost:3030/table?textfield[$like]=andreas
returns:
{
"total": 1,
"limit": 20,
"skip": 0,
"data": [
{
"id": 1,
"textfield": "andreas",
"createdAt": "2017-06-05T11:33:38.000Z",
"updatedAt": null
}
]
}
localhost:3030/table?textfield[$like]=andrea%
returns:
{
"total": 1,
"limit": 20,
"skip": 0,
"data": [
{
"id": 1,
"textfield": "andreas",
"createdAt": "2017-06-05T11:33:38.000Z",
"updatedAt": null
}
]
}
localhost:3030/table?textfield[$like]=%drea%
returns:
{
"total": 1,
"limit": 20,
"skip": 0,
"data": [
{
"id": 1,
"textfield": "andreas",
"createdAt": "2017-06-05T11:33:38.000Z",
"updatedAt": null
}
]
}
The following queries should return nothing because 'andrea' can not be exactly matched in the database and the asterisk (*) is not a wild card in the SQL LIKE syntax https://www.w3schools.com/SQL/sql_like.asp :
localhost:3030/table?textfield[$like]=andrea
localhost:3030/table?textfield[$like]=andrea*
{
"total": 0,
"limit": 20,
"skip": 0,
"data": []
}
I'm trying to make one postgreSQL 9.3 query.The problem is here i have to count all cleaners rated below 4 rating.Here is my query
SELECT count(ratings.score) as below, avg(ratings.score) as avg_rating, cleaners.first_name, cleaners.last_name, cleaners.id, cleaners.created_at
FROM "cleaners"
LEFT JOIN ratings ON ratings.cleaner_id = cleaners.id
GROUP BY cleaners.first_name, cleaners.last_name, cleaners.id, cleaners.created_at
here is the following result:
{
"HTTP_CODE": 200,
"cleaners": [
{
"id": 29,
"rating_below_3_stars": 1,
"avg_rating": "5.0",
"first_name": "asen",
"last_name": "asenov"
},
{
"id": 35,
"rating_below_3_stars": 2,
"avg_rating": "2.5",
"first_name": "Simepl",
"last_name": "cleaner"
}
]
}
The cleaner with id "29" his rating_below_3_stars have to e set to 0
What i want is:
{
"HTTP_CODE": 200,
"cleaners": [
{
"id": 29,
"rating_below_3_stars": 0,
"avg_rating": "5.0",
"first_name": "asen",
"last_name": "asenov"
},
{
"id": 35,
"rating_below_3_stars": 2,
"avg_rating": "2.5",
"first_name": "Simepl",
"last_name": "cleaner"
}
]
}
you count only the ratings below 4
SELECT sum(case when ratings.score<=3 then 1 else null end) as below,
avg(ratings.score) as avg_rating,
cleaners.first_name, cleaners.last_name, cleaners.id,
cleaners.created_at
FROM "cleaners"
LEFT JOIN ratings ON ratings.cleaner_id = cleaners.id
GROUP BY cleaners.first_name, cleaners.last_name, cleaners.id, cleaners.created_at