I have a question about mapping an array of ID's (inputdata) and returning all related documents to those ID's. I have a UDF set up to retrieve the documents for a single ID and was hoping some tweaking would make that work. I can't seem to figure out how to map over the inputdata and create a variable (data:) to store the new array of documents. Any help is appreciated. Here is the single entry UDF which works:
Query(
Lambda(
["inputdata"],
Let(
{
data: Map(
Paginate(
Match(
Index("certificate_by_dealer"),
Ref(Collection("Dealers"), Select("dealer", Var("inputdata")))
)
),
Lambda(["ref"], Get(Var("ref")))
)
},
Select(["data"], Var("data"))
)
)
)
Is there a simple...or any solution to make this work for an array of ID's as inputdata?
Call function is:
Call("user_dealers_all_certificates", {
ids: [301393590798516736, 301393590798516749]
}
Unfortunately I get no results. (Adding quotes solved the issue)
Here is implementing the suggested UDF:
Query(
Lambda(
["inputdata"],
Let(
{ dataIds: Select("ids", Var("inputdata")) },
Union(
Map(
Var("dataIds"),
Lambda(
["id"],
Select(
["data"],
Paginate(
Match(
Index("certificate_by_dealer"),
Ref(Collection("Dealers"), Var("id"))
)
)
)
)
)
)
)
)
)
Adding quotes created a proper response:
Call("user_dealers_all_certificates", {ids: ["302122229239382536", "301394099049595400"]})
[
Ref(Collection("Certificate"), "302122488174739977"),
Ref(Collection("Certificate"), "302120872550859273")
]
However the GraphQL query returns bad data:
query {
allUserDealersCertificate(data: {ids: ["302122229239382536", "301394099049595400"]}){
data {
_id
}
}
}
response:
{
"errors": [
{
"message": "Lambda expects an array with 1 elements. Array contains 4.",
"extensions": {
"code": "invalid argument"
}
}
]
}
GraphQL error without paginated: true in schema:
{
"data": {
"allUserDealersCertificate": [
null,
null
]
},
"errors": [
{
"message": "Cannot return null for non-nullable type (line 3, column 5):\n _id\n ^",
"path": [
"allUserDealersCertificate",
0,
"_id"
],
"locations": [
{
"line": 3,
"column": 5
}
]
},
{
"message": "Cannot return null for non-nullable type (line 3, column 5):\n _id\n ^",
"path": [
"allUserDealersCertificate",
1,
"_id"
],
"locations": [
{
"line": 3,
"column": 5
}
]
}
]
}
Based on the query you provided, I feel the need to point out that the Match function performs exact matches. It does not (and cannot) unroll a structured array for you. Neither can the Ref function.
You'd need to call Map on the inputdata, and get results for each id. Then you can Union those results together into a single list.
I don't know the exact shape of the data that you're dealing with, so here's a query that works with the pre-populated data available in the Dashboard:
Let(
{
// the pre-populated data has 3 stores, with ids 301, 302, and 303
// here, we want the products in stores 301 and 302
ids: [ 301, 302 ]
},
// this is where we combine all of the results
Union(
Map(
// here is where we loop over the list of ids
Var("ids"),
Lambda(
// for each id, run this function's expression
"id",
Select(
// each Paginate call returns a page of results with its own data
// field, so we have to select those out
"data",
Paginate(
Match(
Index("products_by_store"),
// here we compose a reference to a specific store, using the
// Lambda function's current id
Ref(Collection("stores"), Var("id"))
)
)
)
)
)
)
)
Npte that I've used Let to simulate passing an array to the body of a UDF. When you run this query, the result should be:
[
["avocados", "Conventional Hass, 4ct bag", 3.99],
["cilantro", "Organic, 1 bunch", 1.49],
["limes", "Conventional, 1 ct", 0.35],
["limes", "Organic, 16 oz bag", 3.49],
["cups", "Translucent 9 Oz, 100 ct", 6.98],
["pinata", "Giant Taco Pinata", 23.99],
["pinata", "Original Classic Donkey Pinata", 24.99]
]
I would like to sort with strapi's graphql
I can do that by
{
users (sort: "id:asc") {
id
username
email
address {
id
city
state
street
}
}
}
I can sort by the first level of columns but how do I go deeper, for example address.city, because
". / :" don't work, graphql playground returns:
"errors": [
{
"message": "select \"users\".* from \"users\" order by \"address\".\"city\" desc limit $1 - missing FROM-clause entry for table \"address\"",
I have two tables reels and reel_variations, reels can have many reel_variations and reel_variations belong to one reel. I have read the Hasura docs and haven't been able to figure out how to insert a reel and a couple of reel variations in a single mutation.
mutation insertReelsAndVariations($objects: [reels_insert_input!]! = {}) {
insert_reels(objects: $objects) {
affected_rows
returning {
description
id
name
variations {
ball_bearings
braid_capacity
created_at
deleted_at
gear_ratio
max_drag
line_capacity
id
model_number
recovery
reel_id
retrieve
}
}
}
}
Variables
{
"objects": {
"name": "nice reel",
"description": "wicked nice reel",
"variations": {
"data": {
"ball_bearings": "djjdfkjdkjfdjkfjkd",
"braid_capacity": "dkfjdkfjkdf",
"gear_ratio": "20:1",
"max_drag": "20lbs",
"line_capacity": "400yrds",
"model_number": "jfdkjfkjdkfjkdjfjdf",
"recovery": "30 per turn"
}
}
}
}
Errors
{
"errors": [
{
"extensions": {
"path": "$.selectionSet.insert_reels.args.objects[0].variations.data",
"code": "constraint-violation"
},
"message": "Not-NULL violation. null value in column \"reel_id\" violates not-null constraint"
}
]
}
That's because the reel_id column is not set as a foreign key col referencing the reels table. So u can simply:
Make the reel_id col a foreign key which points to the id column of reels table!
wanted to ask if it is possible to upsert nested objects? for example, if i have a 'Users' table and a 'Students' table, and I'm inserting a new User(with a taken id), i want to update all fields (using on_conflict and update_columns) including the fields in the 'Students' table.
Basically replace all user's fields except the primary key.
mutation($UsersData: [core_users_insert_input!]!) {
insert_core_users(
objects: $UsersData
on_conflict: {
constraint: core_users_id_unique
update_columns: [first_name, last_name, gender]
}
) {
affected_rows
}
}
The update_column array should include fields from the 'Students' table but i can't figure it out.
It is possible, relevant documentation is here: https://hasura.io/docs/1.0/graphql/manual/mutations/upsert.html#upsert-in-nested-mutations
It is possible to use on_conflict key on any level (top, or nested) where you want to resolve updating an existing record.
mutation upsert_author_article {
insert_author(
objects: [
{
name: "John",
articles: {
data: [
{
title: "Article 3",
content: "Article 3 content"
}
],
on_conflict: {
constraint: article_title_key,
update_columns: [content]
}
}
}
]
) {
affected_rows
}
}
I've a table with (id, price). id is autoincremented. I want to return the id and full data of last inserted row.
Resolver:
{
"version": "2018-05-29",
"statements": [
"insert into notes (price) VALUES (100)",
"select * from notes WHERE id = $id"
]
}
How can I find the id of last inserted row. Second query of course will not work here as id is not known.
Does SELECT LAST_INSERT_ID(); work well in serverless context? How to store that variable and run third query?
I was running into the same issue. So far, this seems to work for us:
{
"version": "2018-05-29",
"statements": [
"INSERT INTO customer_addresses (`id`, `customerid`, `firstname`, `lastname`) VALUES (NULL, :CUSTOMERID, :FIRSTNAME, :LASTNAME)",
"SELECT * FROM customer_addresses WHERE id = LAST_INSERT_ID()"
],
"variableMap": {
":CUSTOMERID": $context.args.customerid,
":FIRSTNAME": "$context.args.input.firstname",
":LASTNAME": "$context.args.input.lastname"
}
}