I am currently using hygraph as CMS. I have two models, posts and tags. I created many to many relation between them. It works when I use the inbuilt content editor.
The problem is that I cannot do the same with API. I can only create one relation at a time.
So is there a way to create multiple relation at once via API?
I figured this out by hit and trial.
mutation MyMutation {
createContent(
data: {title: "ABC", genres: {connect: [{Genre: {type: "travel"}},{Genre: {type: "food"}}]}}
) {
id
}
}
You have to pass array of individual genres to connect.
Related
I hope you’re doing well.
So, I’m creating a database-driven website about Portuguese dubs and using Strapi as backend and CMS.
I created a collection type name Movies that has, amongst other things, a repeatable component for the cast.
This repeatable component is made of a relations component with the Voice Actors collection (one to one) and a text field with the character he played.
When I call the API for a certain movie and populate Cast, it retrieves me the cast. However, it retrieves me the wrong ID for the Voice Actor.
For example, my Voice Actors’ ID go from 16 to 20, whoever the API is returning 10, 11, 12…
How do I retrieve the Voice Actors’ ID?
so let's make it clear you have a collection movies, witch has repeatable components casts witch has relation to an actor.
So id that you have in your screenshot is likely an id of component, to get full data you would need to populate at list two levels deep:
const query = qs.stringify(
{
populate: {
casts: {
populate: ['actor'],
},
},
},
{
encodeValuesOnly: true,
}
);
witch would give request like this:
http://localhost:1337/api/movies?populate[casts][populate][0]=actor
All of the answers I have found relate to graphql. I need to know how to update the cache on the client using apollographql.
Given this Friend type and mutation.
type Friend {
id: String
name: String
friends: [Friend]
}
type Mutation {
createFriend (
friends: [FriendInput]
): [Friend]
}
The friends array is circular. How do you represent this in the response and how do you update the clients cache?
If you're interested in the friends of a specific person, your store probably contains a bunch of Friend objects (I would actually call them Person, and friends is just a field on the Person type). For doing the mutation, it should be enough to provide the id of each friend of that new person, unless you want to create not just one person at a time in these mutations, but multiple.
For the mutation response, just include the data that you need for each friend. If you need the name and id of each of the persons friends, then include that as well. Most likely you won't need to go two levels deep, but if you want to, you can do that as well.
In Apollo Client, you don't actually need to do anything special to have this data be properly written into your store, because Apollo Client automatically normalizes by the id field and stores each friend only once. So if you're sure that you already have all the persons on the client, it will be enough to ask only for the id of each friend, so for example:
{
createFriend( friends: [{ name: 'Joe', friends: [{ id: 1}, {id: 4}] }]) {
id
name
friends {
id
name
}
}
}
I'm using Graph.cool graphql as a service and am wondering how to do a mass update to the collection, similar to a SQL update.
In my case I need to update the suffix of a url, in the imageUrl column of my database. I need to swap out a {someid}_sm.jpg to {someid}_lg.jpg
How do I do that with a graphql mutation? I don't want to reload the entire dataset again and am looking for a way to do it that doesn't involve manually interating through the entire list with a graphql client.
mutation {
updatePost() // what goes here?
}
Migration script
The best approach is indeed to use a migration script that combines multiple mutations so only one HTTP request is sent to the GraphQL backend.
Consider this schema:
type Image {
id: ID!
name: String!
}
We can include the same mutation multiple times in one request with GraphQL aliases:
mutation {
first: updateImage(id: "first-id", name: "01_lg.jpg") {
id
name
}
second: updateImage(id: "second-id", name: "02_lg.jpg") {
id
name
}
}
We'll make use of this mechanism in our migration script. I'll describe it with Lokka and Node, however you can choose whatever language and GraphQL client you prefer.
First, we query all existing images to obtain their id and name:
const queryImages = async() => {
const result = await client.query(`{
images: allImages {
id
name
}
}`)
return result.images
}
Then we replace the names accordingly and construct one big request including the necessary updateImage mutations with a different GraphQL alias for each.
If your image names might contain the string sm in the {someid} part mentioned in your question, this script will break! In that case, please adjust accordingly.
const migrateImages = async(images) => {
// beware! if your ids contain the string 'sm', adjust the string replacement accordingly!
const updateMutations = _.chain(images)
.map(image => ({ id: image.id, name: image.name.replace('sm', 'lg')}))
.map(image => `
${image.id}: updateImage(id: "${image.id}", name: "${image.name}") {
id
name
}`)
.value()
.join('\n')
const result = await client.mutate(`{
${updateMutations}
}`)
console.log(`Updated ${Object.keys(result).length} images`)
console.log(result)
}
That's it. If you have to update thousands of images, batching the mutations in say groups of a hundred might be better than to batch all of them in one request. Note that mutations run sequentially on the GraphQL server.
Running the migration
Currently, I suggest the following workflow for running the migration:
Clone your project
Run the migration script on your cloned project
Verify that the migration ran successfully. Double check :)
Run the migration on your original project
You can find the code and further instructions here.
While this approach is great for migrations that are as straightforward as in your example, it's not perfect for all situations. We're already thinking about creating an integrated experience for this use case, such as an interactive migration right in your Graphcool project, with simulated migrations, checks and more. If you have suggestions, let me know in Slack.
I'm doing a elastic search autocomplete-as-you-type
I'm using cool features like ngram's and other stuff to create needed analyzer.
currently I break my had around indexing following data.
Let say I have Payments type,
each document in this type looks like this
{
..elastic meta data..
paymentId: 123453425342,
providerAccount : {
id: 123456
firstName: Alex,
lastName: Web
},
consumerAccount : {
id: 7575757,
firstName: John,
lastName: Doe
},
amount: 556,
date : 342523454235345 (some unix timestamp)
}
so basically this document represents not only the payment itself but it also shows the relationship of the payment, the 2 entities which related to the payment.
Payment always have its provider and consumer.
I need this data in payment document because I want to show it in UI.
By indexing it like so, it might be a big pain for handling the updates of Consumer or Provider because each time some of them change its properties I have to update all the payments which has this entity.
Another possible solution is to store only id's of this consumers/providers and make a query on payments and then 2 queries for the entities for retrieving needed fields, but i'm not sure about this because i'm doing ajax requests each time a character entered, so here comes the performance question.
I have also looked into parent/child relationship solution which basically fits my case but I wasn't able to figure out if I can retrieve also the parent(consumer/provider) fields while I querying child(payment).
What would you suggest?
Thanks!
Yes, you can retrieve the parent while querying child using has_child.
Considering payment as child and consumer as parent, You can search all the consumers by :
GET /index_name/consumer/_search
{
"query": {
"has_child": {
"type": "payment",
"query": {
// any query on payment table
},
"inner_hits": {}
}
}
}
This would fetch you all the consumer based on the query on child i.e payment in your case.
inner_hits is what you are looking for. This will retrieve you the children as well. But it was introduced in elasticsearch 1.5.0. So version should be greater than elasticsearch 1.5.0.
You can refer https://www.elastic.co/blog/elasticsearch-1-5-0-released.
Your problem is not an issue. I suppose you want tot freeze data after the pay, right? So you don't need to update the accounts data in existing payment documents.
Further: parent/schild is easy for updating, but less efficient with querying. For auto complete, stay using your current mapping!
I have a Post class and I want to get the products associated to it. I'd like to write a single query that fetches all of the posts with the products associated to them. Below is a rough idea of what I'd like the hash to looks like.
Schema:
Post - objectId, title
PostItem - post(pointer), product(pointer)
Product - objectId, title, price
Output I want
{'results':
[{'objectId':'blah', 'title':'The Post',
'products':
[{'objectId':'14',
'title':'First product',
'price':'20'
},
{'objectId':'26',
'title':'Second product',
'price':'55'
}]
},
{'objectId':'blah2', 'title':'Second post',
[{'objectId':'38',
'title':'Some product',
'price':'54'
},
{'objectId':'26',
'title':'Another Product',
'price':'88'
}]
}]
}
Is this possible to do in one query? How would I do this using curl and parse.com?
If this is a many-to-many relationship, use a Parse relationship.
You'll want to use the include key option alongside pointers. Since it's been nearly a year since you posted, I assume you figured it out, but lurkers can read more about this (in Javascript) here.