Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@searchable transforms and connections #763

Closed
helloniklas opened this issue Jan 24, 2019 · 19 comments
Closed

@searchable transforms and connections #763

helloniklas opened this issue Jan 24, 2019 · 19 comments
Assignees
Labels
feature-request Request a new feature graphql-transformer-v1 Issue related to GraphQL Transformer v1

Comments

@helloniklas
Copy link

Is there a way to get the @searchable to also work with @connection. Say I have these models.

type Post @model @searchable {
    id: ID!
    text: String
    votes: [Vote] @connection(name: "PostVotes")
}

type Vote @model @searchable {
    id: ID!
    vote: Int!
    post: Post! @connection(name: "PostVotes")
}

The generated searchVotes query would then only be able to filter on id and vote. But say I want to get all the votes for a certain postId.

Likewise the ListVotes query doesn't either provide a filter on the post connection.

So how would I in this case go about to get all the Votes on a certain post?

@kaustavghosh06 kaustavghosh06 added graphql-transformer-v1 Issue related to GraphQL Transformer v1 question General question labels Jan 24, 2019
@mikeparisstuff
Copy link
Contributor

mikeparisstuff commented Jan 24, 2019

Hey @helloniklas thanks for the question. This is not yet supported, but we would love to support use cases like this in the future. I think the best way to get movement on this would be to propose a design so that we can start getting feedback from the community. We will be investing more in enhancing auth support across the transform so any design should consider what authorization would look like.

@kaustavghosh06 kaustavghosh06 added feature-request Request a new feature and removed question General question labels Jan 28, 2019
@jonmifsud
Copy link

@mikeparisstuff this is a critical part for what we'd need.

@helloniklas's scenario is fairly simple in that you can query posts and then get the votes through the standard GQL connection.

However we are thinking of scenarios where we would need to search across joint datasets. We know in elastic there are different storage models, including structuring flat file nested properties or linking properties (meaning they'd live on the same shard - possible performance causes) - is there anywhere that could point to how we could create custom resolvers to get these to open up in a flat file?

Using the above scenario meaning that the @searchable for Vote would contain both the Vote information + the post information.

@malcomm
Copy link

malcomm commented Dec 3, 2019

@mikeparisstuff, @kaustavghosh06 - Any movement on this? I've run into this a couple of times and I have to just stop and try to go around it a different way. It seems like supporting @searchable and @connection on the basic ID level would be a big win and solve 80% of the issues.

@MilesDowe
Copy link

This gets a +1 from me. Maybe it's been addressed, but I've had difficulty finding documentation online.

Given:

type ObjectA @model @searchable {
  id: ID!
  objectB: ObjectB! @connection(name: "ObjectBToA")
}

type ObjectB @model @searchable {
  id: ID!
  objectAs: [ObjectA] @connection(name: "ObjectBToA")
}

It would be handy to search for ObjectA by the id value of ObjectB.

I've so far been injecting Elasticsearch queries directly by manually modifying the Searchable.*Filter objects over the AppSync UI to have an override string attribute. I then updated their associated Resolvers to use only the override if it's present.

This is unsustainable, though. While I can define the Resolver as a VTL file under ./amplify/backend/api/resolvers, there isn't a way to ensure my override attribute hack gets created when running amplify push, thus breaking code with schema updates.

@beautypassgroup
Copy link

Any movement on this please?

@blkc
Copy link

blkc commented Aug 9, 2020

+1 I ran into this issue today and sadly the current solution is to copy the data over to one of the @model so you can query and update without breaking.

@supercodes1223
Copy link

+1 this is a big issue for us.

@supercodes1223
Copy link

Feedback we got from Amplify team is that they prioritize these issues by their engagement on Github so please upvote this issue and add your comments so this becomes a priority to them. For us not making @connection available to @searchable is a big limitation.

@ericowhadi
Copy link

+1 stumble on the same limitation, big deal.

@jfhidakatsu
Copy link

This would be a great feature, as it would save development time for us.

@alexboulay
Copy link

alexboulay commented Oct 23, 2020

Our team needs this!
I wonder, is this a limit that stems from DynamoDB?

Would I be able to write a custom resolver to go around this limitation?

@KIWI-JP
Copy link

KIWI-JP commented Dec 8, 2020

I have also been needing this for a while on a project, so any progress towards it would be appreciated.

In the meantime, is there any way to do this with a custom resolver? @alexboulay did you find a way around it?

@alexboulay
Copy link

@KIWI-JP I ended up putting all the search terms in a list within the objects that I wanted to search. Its not the cleanest solution but it does work!

@yannikw23
Copy link

Are there any updates on this? Any help would be appreciated!

@josefaidt josefaidt self-assigned this Mar 29, 2022
@josefaidt
Copy link
Contributor

Hey y'all 👋 I wanted to follow-up on this one and show how this is now possible with GraphQL Transformer v2 and the new relational directives! Using the following schema we will be able to create a Post, create a Vote linked to the Post, then run a search query by post ID.

type Post @model @searchable {
  id: ID!
  text: String
  votes: [Vote] @hasMany
}

type Vote @model @searchable {
  id: ID!
  vote: Int!
  post: Post!
}

Then we can execute the following in order to ultimately search Votes by Post ID

mutation CREATE_POST {
  createPost(input: {text: "my first post"}) {
    id
  }
}

mutation CREATE_VOTE {
  createVote(input: {vote: 10, postVotesId: "a7173361-d420-44fd-abb9-88b26f7a506b"}) {
    id
  }
}

query SEARCH_BY_ID {
  searchVotes(filter: {postVotesId: {eq: "a7173361-d420-44fd-abb9-88b26f7a506b"}}) {
    items {
      id
      postVotesId
      vote
    }
  }
}

Where the search query will return:

{
  "data": {
    "searchVotes": {
      "items": [
        {
          "id": "34caeece-2530-452c-8965-0f3d097b545c",
          "postVotesId": "a7173361-d420-44fd-abb9-88b26f7a506b",
          "vote": 10
        }
      ]
    }
  }
}

Closing issue 🙂 if you feel this does not quite cover your use case please reply back to this thread and we can re-open to investigate further!

@Hoxni
Copy link

Hoxni commented May 18, 2022

How to search votes by text in related posts? For example how to get votes, where related post contains word "test" in field text?

@majirosstefan
Copy link

majirosstefan commented Aug 21, 2023

I am using GraphQL Transformer v2.

If you need to search votes by text in related posts in the schema above, you should re-evaluate your access patterns.
This is typically you taking a look on how the data is accessed in your app, and then you would model relationships based on that in (the schema.graphqhl).

To search votes by text in related posts, you can search posts by text first and then just tell AppSync to append corresponding posts:

query SEARCH_POSTS {
  searchPostsThatEndsWithPost: searchPosts(filter: {text: {wildcard: "*post"}}) { **// search posts where text ends with post word**
    items {
      id
      votes {  **// sub-select votes**
        items {
          id
          vote
        }
        nextToken
      }
    }
  }
}

That query above would give you something like this:

Screenshot 2023-08-21 at 7 32 03 PM

If response is containing non-null nextToken somewhere, usually it means there are more results to be fetched.

Here you can see how to pass nextToken to the outer search results (data.searchPostsThatEndsWithPost.items):
https://docs.amplify.aws/cli/graphql/search-and-result-aggregations/#paginate-over-search-results

Screenshot 2023-08-21 at 7 39 21 PM

But if those search results looks like this (indicating that not the all of nested votes have not been fetched):

Screenshot 2023-08-21 at 7 50 12 PM

You would either need to bump limit for sub-selection or you would need to pass nextToken to inner searchPostsThatEndsWithPost.items.votes.nextToken like this:


query SEARCH_POSTS {
  searchPostsThatEndsWithPost: searchPosts(filter: {text: {wildcard: "*post"}}) {
    items {
      id
      votes (nextToken:"ey....fQ==") {
        items {
          id
          vote
        }
        nextToken
      }
    }
    nextToken
  }
}

The problem with that is that nextToken is applied to every subselection and you would get also this error:

The provided starting key is outside query boundaries based on provided conditions (Service: DynamoDb, Status Code: 400, Request ID: 3NPOT84B4B09GRITQGLGH2E32BVV4KQNSO5AEMVJF66Q9ASUAAJG)

Screenshot 2023-08-21 at 8 08 25 PM

so in that case (fetching nested items) you would need to narrow down the search query to get only one post and the query would look like:

query SEARCH_POSTS {
  searchPostsThatEndsWithPost: searchPosts(filter: {text: {wildcard: "*post", and: {id: {eq:"3666e229-6134-4d6e-95ed-06906ce70d85"}}}}) {
    items {
      id
      votes (limit:1, nextToken:"ey==") {
        items {
          id
          vote
        }
        nextToken
      }
    }
    nextToken
  }
}

It's not intuitive to use this approach, but it seems to be possible.

Another approach (that I would prefer) would be

  • to retrieve searched posts + nested votes using searchQuery (using default or increased limits of Appsync // bump filter parameter for sub-selections)
  • and then if you need to load more votes for given post, you can use listVotes query (with some filtering or you would add new "@index" for that field (previously named "@key") to support that new access pattern
query listVotes {  
  listVotes(filter: {postVotesId: {eq:"3666e229-6134-4d6e-95ed-06906ce70d85"}}){
    items {
      id
      vote
    }
    nextToken
  }
}

Screenshot 2023-08-21 at 8 39 52 PM

@johndebord
Copy link

johndebord commented Oct 21, 2023

I have two types:

type Post
  @model
  @searchable {
  hash: String! @primaryKey
  user: User! @hasOne
}
type User
  @model
  @searchable {
  sub: String! @primaryKey
  username: String!
}

I would like to search for Posts by the user's username like so:

let searchPostsResult = await API.graphql({
  authMode: GRAPHQL_AUTH_MODE.AWS_IAM,
  query: searchPosts,
  variables: {
    filter: {
      user: {
        username: {
          matchPhrasePrefix "asdf",
        },
      },
    },
  },
});

However, this is impossible. Or is it? Is there a way to achieve something like this?

@johndebord
Copy link

Is this still not possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request a new feature graphql-transformer-v1 Issue related to GraphQL Transformer v1
Projects
None yet
Development

No branches or pull requests