How to query multiple document refs in GraphQL

I have the following graphQL Schema. I want to query the Decor type by multiple reference ID’s. I have an array of Decor documents in a string and I want to query all the Decor types in one query.

type Catalog {
  decor: Boolean
  clothing: Boolean
  supplies: Boolean
  furniture: Boolean
  owner: User
}

type Decor {
  description: String
  pieces: Int
  purchaser: String
  alterations: Boolean
  cost: Int
  purchaseDate: Date
  category: String
  image: String
  itemNum: Int
  owner: User!
  visible: Boolean
}

type DecorSheet {
  sheetName: String
  refIdArray: String
  owner: User!
}

type User {
  email: String! @unique
  catalog: Catalog
  decor: [Decor!] @relation
  decorSheet: [DecorSheet!] @relation
}

So if I have the following graphQL query, is there a way to pass multiple id’s to it and get all the matching. Do I need to structure my schema differently?

const DECOR = gql`
  query GetDecor($id: ID!) {
    findDecorByID(id:$id){ //CAN I PASS MULTIPLE ID'S HERE
      purchaseDate
      visible
      _id
      ...
    }
  }
`;

If this is not possible. Can I do this with FQL, passing in multiple ID’s and receiving back all the matches.

Thanks ahead of time. :smiley:

I’ve read this question, but don’t quite grasp how it might help

@anders You cannot do this with the default findDecorByID. However, you can write a query with the @resolver directive, which accepts a list of refs. You can use Map[list of refs] in the corresponding UDF, Paginate, Lambda, Get to get the data. I hope this helps.

@Jay-Fauna
How would one write this query would it be something like this, I know the @resolver part will create a blank udf for me to modify, but what to put in this query so I can pass a list of ref’s I am not sure.

type Query{
    AllDecorByID:[ID] @resolver (name: "grabAll")
  } 

Here is an example.

Schema File

type User {
    userName: String!
    userAccounts: [Account!] @relation(name: "account_has_users")
}

type Account {
    accountId: String!
    accountUsers: [User!] @relation(name: "account_has_users")
}

input CreateUserInput {
    username: String!
    accountId: String!
}

type Query {
    allUsers : [User!]
    allAccounts: [Account!]
    getUserAccounts(UserId: ID!): [Account!] @resolver(name: "get_user_accounts", paginated: true)
    getMulitpleUsers(UserId: [ID!]): [User!] @resolver(name: "get_multiple_users")

}

type Mutation {
    createUserAndAccount(input: CreateUserInput): User! @resolver(name: "create_user_and_account")
}

Here is the UDF for getMulitpleUsers

Update(
  Function("get_multiple_users"), {
    body: Query(
      Lambda(
        ["input"],
        Let({
            data: Map(
              get_multiple_users Lambda("x", Get(Ref(Collection("User"), Var("x")))))
          },
          Select(["data"], Var("data"))
        )
      )
    )
  }
)

@Jay-Fauna Ok awesome I will try this out, thanks for the help. Need hand holding sometimes. Cheers

@Jay-Fauna
I’ve tried the following, changing it for my data, and Fauna is complaining I am missing a ) but I don’t see it, do you?

Actually I think there is a missing comma here but the that array in the map is undefined???

get_multiple_decors, Lambda("x", Get(Ref(Collection("User"), Var("x")))))
Update(
  Function("get_multiple_decors"), {
    body: Query(
      Lambda(
        ["input"],
        Let({
            data: Map(
              get_multiple_decors Lambda("x", Get(Ref(Collection("User"), Var("x")))))
          },
          Select(["data"], Var("data"))
        )
      )
    )
  }
)

Update: I have tried the following to no avail

Update(
    Function("get_multiple_decors"), {
      body: Query(
        Lambda(
          ["input"],
          Let({
              data: Map(
                Select(["DecorId"],Var("input")), Lambda("x", Get(Ref(Collection("Decor"), Var("x")))))
            },
            Select(["data"], Var("data"))
          )
        )
      )
    }
  )

this is the query I have created

type Query {
  getMultipleDecors(DecorId: [ID!]): [Decor]
    @resolver(name: "get_multiple_decors")
}

Var("input") should be the array passed in, it looks like you are trying to use it like an object.

If you’re a “console.log enthusiast” You can check that with an Abort:

Update(Function('get_multiple_decors'), {
  body: Query(
    Lambda(
      ['input'],
      Abort(Format('%@', [Var('input')]))
    )
  )
})

// call from shell
Call(Function("get_multiple_decors"), [["111", "222", "333"]])

In any case, have you tried to use just the variable by itself? Jay left in a couple of typos for you to work out – really make sure you know what you’re doin’ :wink: :yum:

// ...
  data: Map(
    Var("get_multiple_decors"),  // <= note wrapped in `Var` function
    Lambda("x", Get(Ref(Collection("User"), Var("x"))))
  )
// ...

Otherwise, it looks like you’re doing it right :slight_smile:

1 Like

@anders Apologize, I pasted a wrong UDF. Here is the correct one. You

 Update(
   Function("get_multiple_users"), {
     body: Query(
       Lambda(
         ["input"],
         Let({
             data: Map(
               Var("input"),
               Lambda("x", Get(Ref(Collection("User"), Var("x")))))
           },
           Var("data")
         )
       )
     )
   }
 )

You can test this from Shell

Call(Function("get_multiple_users"), [["291963324717859331", "291964514840084995"]])

[
  {
    ref: Ref(Collection("User"), "291963324717859331"),
    ts: 1614698029760000,
    data: {
      userName: "jay@fauna.com"
    }
  },
  {
    ref: Ref(Collection("User"), "291964514840084995"),
    ts: 1614698052700000,
    data: {
      userName: "jay1@fauna.com"
    }
  }
]

GraphQL API expects an Array of Users
getMulitpleUsers(UserId: [ID!]): [User!] @resolver(name: "get_multiple_users")
so, you have to make sure UDF returns the Array of Users.

2 Likes