My table contains documents that look like this:
[{ user: {
key: '100'
},
product: {
name: 'Product 1',
tags: [ 'tag1', 'tag2' ],
}
}, { user: {
key: '100'
},
product: {
name: 'Product 1',
tags: [ 'tag1', 'tag3' ],
}
}, ...]
I would like to create a query which would
groupe documents by the user.key field (1 document per user on result),
the product.tags would be an object (instead of array) with tag occurrences count for each tag.
Result example:
[ { user: {
key: '100'
},
product: {
name: 'Product 1',
tags: {
tag1: 2, // tag1 found 2x for user.key=100
tag2: 1, // tag2 found 1x for user.key=100
tag3: 1
}
}
}, ...]
I think I could do this by mapping and reducing but I have problems - I'm using rethinkdb for the first time.
Here's a way to do it:
// Group by user key
r.table('30400911').group(r.row('user')('key'))
// Only get the product info inside the reduction
.map(r.row('product'))
.ungroup()
.map(function (row) {
return {
user: row('group'),
// Group by name
products: row('reduction').group('name').ungroup().map(function (row) {
return {
name: row('group'),
// Convert array of tags into key value pairs
tags: r.object(r.args(row('reduction').concatMap(function (row) {
return row('tags')
}).group(function (row) {
return row;
}).count().ungroup().concatMap(function (row) {
return [row('group'), row('reduction')]
})))
}
})
}
})
For the following data:
{
"id": "0565e91a-01ca-4ba3-b4d5-1043c918c79d" ,
"product": {
"name": "Product 2" ,
"tags": [
"tag1" ,
"tag3"
]
} ,
"user": {
"key": "100"
}
} {
"id": "39999c9f-bbef-4cb7-9311-2516ca8f9ba1" ,
"product": {
"name": "Product 1" ,
"tags": [
"tag1" ,
"tag3"
]
} ,
"user": {
"key": "100"
}
} {
"id": "566f3b79-01bf-4c29-8a9c-fd472431eeb6" ,
"product": {
"name": "Product 1" ,
"tags": [
"tag1" ,
"tag2"
]
} ,
"user": {
"key": "100"
}
} {
"id": "8e95c467-cedc-4734-ad4d-a1f7a371efd5" ,
"product": {
"name": "Product 1" ,
"tags": [
"tag1" ,
"tag2"
]
} ,
"user": {
"key": "200"
}
}
The results would be:
[
{
"products": [
{
"name": "Product 1" ,
"tags": {
"tag1": 2 ,
"tag2": 1 ,
"tag3": 1
}
}, {
"name": "Product 2" ,
"tags": {
"tag1": 1 ,
"tag3": 1
}
}
],
"user": "100"
} ,
{
"products": [
{
"name": "Product 1" ,
"tags": {
"tag1": 1 ,
"tag2": 1
}
}
] ,
"user": "200"
}
]
Related
**i want **
$PlanDetails= PalnCategory::select('id','title')->with('Categorys'[subplandetails])->get();
my api response
[
{
"id": 1,
"title": "category 1",
"categorys": [
{
"id": 5,
"subcategor_name": "regular"
},
{
"id": 6,
"subcategor_name": "primum"
}
]
},
{
"id": 2,
"title": "category 2",
"categorys": [
{
"id": 7,
"subcategor_name": "cat2 reg"
}
]
}
]
i want to show
[
{
"id":1,
"title":"category 1",
"categorys":[
{
"id":5,
"subcategor_name":"regular",
"plans":[
{
"id":1,
"name":"plan1"
},
{
"id":2,
"name":"plan2"
}
]
},
{
"id":6,
"subcategor_name":"primum",
"plans":[
{
"id":3,
"name":"plan3"
},
{
"id":4,
"name":"plan4"
}
]
}
]
},
{
"id":2,
"title":"category 2",
"categorys":[
{
"id":7,
"subcategor_name":"cat2 reg",
"plans":[
{
"id":3,
"name":"plan3"
},
{
"id":4,
"name":"plan4"
}
]
}
]
}
]
my model
public function Categorys()
{
return $this->belongsToMany(PlanSucategory::class)->select('id','subcategor_name');
}
public function PlanDetails()
{
return $this->belongsToMany(PlanDetail::class);
}
my controller
$PlanDetail= PalnCategory::select('id','title')->with('Categorys','PlanDetails')->get();
return response()->json($PlanDetail);
here subcategories id same anthor to table categories<-subcategories->plandetails but i want to fetch data categories->subcategories->plandetails
here subcategories id same anthor to table categories<-subcategories->plandetails but i want to fetch data categories->subcategories->plandetailshere subcategories id same anthor to table categories<-subcategories->plandetails but i want to fetch data categories->subcategories->plandetails
I'm not going to modify your query, but instead use a collection, which will transform the data after the get() method.
$PlanDetail = PalnCategory::select('id','title')
->with('Categorys','PlanDetails')
->get()
->groupBy('categorys.0.id')
->values()
->map(function($item){
$sub = collect($item)->map(function($item){
$return = collect($item)->forget(['categorys', 'plan_details'])->all();
$return['plans'] = $item['plan_details'];
return $return;
})->toArray();
$category = $item[0]['categorys'][0];
$category['categorys'] = $sub;
return $category;
});
return response()->json($PlanDetail);
Output :
[
{
"id": 1,
"title": "category 1",
"categorys": [
{
"id": 5,
"subcategor_name": "regular",
"plans": [
{
"id": 6,
"details": "plan1 reg"
}
]
},
{
"id": 6,
"subcategor_name": "primum",
"plans": [
{
"id": 7,
"details": "plan2 reg2"
}
]
}
]
},
{
"id": 2,
"title": "category 2",
"categorys": [
{
"id": 7,
"subcategor_name": "cat2 reg",
"plans": [
{
"id": 8,
"details": "plan1"
}
]
}
]
}
]
I cannot mutate a list of objects completely, because only the last element of the array will be mutated.
What already works perfectly is, if I put each element ({play_positions_id: ...}) in the array manually like here:
mutation CreateProfile {
__typename
create_profiles_item(data: {status: "draft", play_positions: [{play_positions_id: {id: "1"}}, {play_positions_id: {id: "2"}}]}) {
id
status
play_positions {
play_positions_id {
abbreviation
name
}
}
}
}
Output:
{
"data": {
"__typename": "Mutation",
"create_profiles_item": {
"id": "1337",
"status": "draft",
"play_positions": [
{
"play_positions_id": {
"id": "1",
"abbreviation": "RWB",
"name": "Right Wingback"
}
},
{
"play_positions_id": {
"id": "2",
"abbreviation": "CAM",
"name": "Central Attacking Midfielder"
}
}
],
}
}
}
Since you can add many of those elements, I defined a variable/argument like here
mutation CreateProfile2($cpppi: [create_profiles_play_positions_input]) {
__typename
create_profiles_item(data: {status: "draft", play_positions: $cpppi}) {
id
status
play_positions {
play_positions_id {
id
abbreviation
name
}
}
}
}
Variable object for above:
"cpppi": {
"play_positions_id": {
"id": "1"
},
"play_positions_id": {
"id": "2
}
}
Output:
{
"data": {
"__typename": "Mutation",
"create_profiles_item": {
"id": "1338",
"play_positions": [
{
"play_positions_id": {
"id": "2",
"abbreviation": "CAM",
"name": "Central Attacking Midfielder"
}
}
],
}
}
}
Schema:
input create_profiles_input {
id: ID
status: String!
play_positions: [create_profiles_play_positions_input]
}
input create_profiles_play_positions_input {
id: ID
play_positions_id: create_play_positions_input
}
input create_play_positions_input {
id: ID
abbreviation: String
name: String
}
At the last both snippets, only the last object with the id "2" will be mutated. I need these to use the defined input type from my backend.
I figured it out. I got it wrong with the brackets in the variable. Here the solution:
"cpppi": [
{
"play_positions_id": {
"id": "1"
}
},
{
"play_positions_id": {
"id": "2"
}
}
]
How query only those users whose Itemcount > 10 from the complex nested object(with dynamic key) from comosdb using sql api? UDF not preferred.
Something like,
Select c.username from c where c.Data[*].Order.ItemCount > 10;
{
{
"Username": "User1",
"Data": {
"RandomGUID123": {
"Order": {
"Item": "ItemName123",
"ItemCount" : "40"
},
"ShipmentNumber": "7657575"
},
"RandomGUID976": {
"Order": {
"Item": "ItemName7686"
"ItemCount" : "7"
},
"ShipmentNumber": "876876"
}
}
},
{
"Username": "User2",
"Data": {
"RandomGUID654": {
"Order": {
"Item": "ItemName654",
"ItemCount" : "9"
},
"ShipmentNumber": "7612575"
},
"RandomGUID908": {
"Order": {
"Item": "ItemName545"
"ItemCount" : "6"
},
"ShipmentNumber": "6454"
}
}
}
}
I'm not sure about how to handle unknown keys, but if you're willing to model the key as a value instead (simpler and cleaner I'd argue), you could have:
{
"Username": "User1",
"Data": [
{
"Id": "RandomGUID123",
"Order": {
"Item": "ItemName123",
"ItemCount": 40
},
"ShipmentNumber": "7657575"
},
{
"Id": "RandomGUID976",
"Order": {
"Item": "ItemName7686",
"ItemCount": 7
},
"ShipmentNumber": "876876"
}
]
}
With a query like:
SELECT DISTINCT VALUE(c.Username)
FROM c
JOIN (SELECT VALUE d from d IN c.Data where d["Order"].ItemCount > 10)
Result:
[
"User1"
]
"Order" is a reserved keyword and requires the bracket syntax to reference.
As Noah answers,model the key as a value is a way to achieve.
Additionally,there is another way to achieve without changing your schema of your document .Create UDF like this:
function getResult(data){
for(var key in data){
const itemCount = data[key].Order.ItemCount;
if (parseFloat(itemCount).toString() != "NaN" && parseFloat(itemCount) > 10 ) {
return true;
}
}
return false;
}
Then run this sql:
SELECT c.Username FROM c where udf.getResult(c.Data)
Result:
[
{
"Username": "User1"
}
]
I use following terraform code to get a list of available db resources:
data "alicloud_db_instance_classes" "resources" {
instance_charge_type = "PostPaid"
engine = "PostgreSQL"
engine_version = "10.0"
category = "HighAvailability"
zone_id = "${data.alicloud_zones.rds_zones.ids.0}"
multi_zone = true
output_file = "./classes.txt"
}
And the output file looks like this:
[
{
"instance_class": "pg.x4.large.2",
"storage_range": {
"max": "500",
"min": "250",
"step": "250"
},
"zone_ids": [
{
"id": "cn-shanghai-MAZ1(b,c)",
"sub_zone_ids": [
"cn-shanghai-b",
"cn-shanghai-c"
]
}
]
},
{
"instance_class": "pg.x8.medium.2",
"storage_range": {
"max": "250",
"min": "250",
"step": "0"
},
"zone_ids": [
{
"id": "cn-shanghai-MAZ1(b,c)",
"sub_zone_ids": [
"cn-shanghai-b",
"cn-shanghai-c"
]
}
]
},
{
"instance_class": "rds.pg.c1.xlarge",
"storage_range": {
"max": "2000",
"min": "5",
"step": "5"
},
"zone_ids": [
{
"id": "cn-shanghai-MAZ1(b,c)",
"sub_zone_ids": [
"cn-shanghai-b",
"cn-shanghai-c"
]
}
]
},
{
"instance_class": "rds.pg.s1.small",
"storage_range": {
"max": "2000",
"min": "5",
"step": "5"
},
"zone_ids": [
{
"id": "cn-shanghai-MAZ1(b,c)",
"sub_zone_ids": [
"cn-shanghai-b",
"cn-shanghai-c"
]
}
]
}
]
And I want to get the one that's cheapest.
One way to do so is by sorting with storage-range.min, but how do I sort this list based on 'storage_range.min'?
Or I can filter by 'instance_class', but "alicloud_db_instance_classes" doesn't seem to like filter as it says: Error: data.alicloud_db_instance_classes.resources: : invalid or unknown key: filter
Any ideas?
The sort() function orders lexicographical and you have no simple key here.
You can use filtering with some code like this (v0.12)
locals {
best_db_instance_class_key = "rds.pg.s1.small"
best_db_instance_class = element( alicloud_db_instance_classes.resources, index(alicloud_db_instance_classes.resources.*.instance_class, best_db_instance_class_key) )
}
(Untested code)
We are trying to update a single answer in our sub sub array.
However our query is causing the following error:
{
"deleted": 0 ,
"errors": 1 ,
"first_error": "Inserted value must be an OBJECT (got ARRAY):
[
{
"answers": [
{
"answer": "wassup",
"owner": 12201836
}
],
"question": "Vraag 1?",
"questionId": 0,
"time": "10"
},
{
"answers": [],
"question": "Vraag 2?",
"questionId": 1,
"time": "15"
},
{
"answers": [],
"question": "Vraga 3?",
"questionId": 2,
"time": "20"
}
]" ,
"inserted": 0 ,
"replaced": 0 ,
"skipped": 0 ,
"unchanged": 0
}
Our table structure looks like the following:
Youtube
- Id
- Course
- Unit
- Session
- Number
- Group
- Questions (array)
- Question Id
- Time
- Answers (array)
- Id
- Answer
- Owner
Our query:
r.db('GitSmurf')
.table('youtube')
.update(function (row) {
return row('questions').merge(function (q) {
return r.branch(q('questionId').eq(0), { "answers": q('answers').merge(function(answer) {
return r.branch(answer('owner').eq(12201836), {"answer": "wassup"}, {})} )},{})
})
})
Test content:
{
"completed": [ ],
"course": "swd" ,
"group": "dwa-group-b" ,
"id": "44443377-ed15-4358-a005-f561e7b6a42d" ,
"number": 1 ,
"session": 1 ,
"unit": 1,
"questions": [
{
"answers": [
{
"answer": "hallo" ,
"owner": 12201836
}
] ,
"question": "Vraag 1?" ,
"questionId": 0 ,
"time": "10"
} ,
{
"answers": [ ],
"question": "Vraag 2?" ,
"questionId": 1 ,
"time": "15"
} ,
{
"answers": [ ],
"question": "Vraga 3?" ,
"questionId": 2 ,
"time": "20"
}
] ,
}
Any help is greatly appreciated!
We forgot to return a new object in the update query.
When we added that it worked.
r.db('GitSmurf')
.table('youtube')
.update(function (row) {
return { questions: row('questions').merge(function (q) {
return r.branch(q('questionId'), { "answers": q('answers').merge(function(answer) {
return r.branch(answer('owner').eq(12201836), {"answer": "tom"}, {})
})},{})
})}
})