Search code examples
amazon-web-servicesgraphqlamazon-dynamodbaws-amplifyaws-appsync

AWS amplify Graph QL filter by book title and author name


AWS amplify DynamoDB Graph QL filter by book title and author name

i want to search books by book title and author name but my schema allow me to search books by book title and author ID not author name how i can achieve this.

following is my graph ql schema

type Author 
  @model(subscriptions: null)
  @auth(
    rules: [
      # allow admins to create, update and delete books
      { allow: groups, groups: ["owner"] }
      # allow all authenticated users to view books
      { allow: private, operations: [read] }
    ]
  )
  @key(name: "authorByCreatedAt", fields: ["isDeleted", "createdAt"], queryField: "authorByCreatedAt")
  {
  id: ID!
  name: String!
  description: String!
  status : Boolean!
  createdAt: String!
  image: String!
  isDeleted: Int!
  books: [Book] @connection(keyName: "byAuthor", fields: ["id"])
}

type Book 
  @model(subscriptions: null)
  @auth(
    rules: [
      # allow admins to create, update and delete books
      { allow: groups, groups: ["owner"] }
      # allow all authenticated users to view books
      { allow: private, operations: [read] }
    ]
  )
  @key(name: "bookByCreatedAt", fields: ["isDeleted", "createdAt"], queryField: "bookByCreatedAt")
  @key(name: "byAuthor", fields: ["authorId"])
  {
    id: ID!
    title: String!
    description: String!
    image: String!
    age: Int!
    region: String!
    isbn: String
    narrator: String
    status : Boolean!
    createdAt: String!
    isDeleted: Int!
    book: String!
    bookType: BookType!
    authorId: ID!
    authors: Author @connection(fields: ["authorId"])
  }

enum BookType {
  AUDIO
  EPUB
}


Solution

  • If you are coming from the world of relational databases, this might seem like it should be trivial. In the world of DynamoDB it is more complex. You cannot create a @key that is linked to a @connection ( as far as I understand ). Some solutions to this problem:

    1: Add Author's Name to Book

    The author's name doesn't change typically, so you could do the below. Duplicating data is not frowned upon in DynamoDB/NoSQL world. This will give you a faster query as well.

    type Book 
      @model(subscriptions: null)
      @key(name: "BooksByAuthorName", fields: ["authorName"], queryField: "getBooksByAuthorName")
      {
        id: ID!
        title: String!
        description: String!
        image: String!
        age: Int!
        region: String!
        isbn: String
        narrator: String
        status : Boolean!
        createdAt: String!
        isDeleted: Int!
        book: String!
        bookType: BookType!
        authorId: ID!
        authorName: String
        authors: Author @connection(fields: ["authorId"])
      }
    

    2: Custom Resolvers

    Custom resolvers, like @function ( Lambda functions ), or the more complex custom resolver templates can be used for multiple searches, and custom logic, though I would suggest option 1 first.

    3: Exploring @searchable directive

    See this for more info