List references

This may be related to another issue I submitted a post on.
My playedAs field is defined in the schema as an array because one user may be a player in many different rankings:

type User {
active: Boolean!
username: String!
description: String
email: String
mobile: String
playedAs: [Player!]! @relation
}

type Player {
rank: Int!
ranking: Ranking! @relation
challenger: User @relation
}

type Ranking {
active: Boolean!
rankingname: String!
rankingdesc: String
player: Player
}

type Mutation {
  
  createNewRanking(active: Boolean!, rankingname : String!, rankingdesc : String, rankingownerid : String!): Ranking! @resolver(name: "create_new_ranking")
  createNewUser(active: Boolean!, username : String!, password : String!, description: String, email: String, mobile: String): loginResult! @resolver(name: "create_new_user")
  loginUser(username: String!, password: String!): loginResult! @resolver(name: "login_user")
}

type Query {
  allUserNames: [String!]! @resolver(name: "all_user_names")
  allPlayerUIDs: [String!]! @resolver(name: "all_player_uids")
  allPlayerRanks: [Int!]! @resolver(name: "all_player_ranks")
  allPlayerChallengerUIDs: [String!]! @resolver(name: "all_player_challenger_uids")
  allPlayers: [Player] @resolver(name: "all_players")
  allRankings: [Ranking] @resolver(name: "all_rankings")
  allUsers: [User] @resolver(name: "all_users")
  gotPlayersByRankingId (rankingid: String!): [Player] @resolver(name: "got_players_byrankingid")
  gotRankingIdsByPlayer (uid: String!): [String] @resolver(name: "got_rankings_byplayerid")
}

type loginResult @embedded
{
  token : String
  logginUser : User
}

However, if I attempt to add (via ‘new document’ in the Fauna UI) more than 1 player to the playedAs field e.g.:

{
active: true,
username: "Test1",
description: "right hander",
email: "t1@t1.com",
mobile: "+65 1111 1111",
playedAs: Ref(Collection("Player"), ["287674108858073605","287674596064231937"])
}

I get:

String or Number expected, Array provided.

How should I represent multiple ‘playedAs’ player references here? thanks …

The way the DB will set this up, is to have each Player document store a User reference in the challenger field. And there will be an index automatically created for you that indexes all the documents in the Player collection by their challenger field. That way the system can find all the Players for a given User. So the User.playedAs field doesn’t really exist in a User document in the database. It’s more of a virtual field backed by an index. If you want to add more players to a User, you just need to create Player documents with the correct User reference in the challenger field.

p.s.
It looks like you might be missing an @relation directive here:

type Ranking {
active: Boolean!
rankingname: String!
rankingdesc: String
player: Player @relation <-- here
}

@wallslide nailed it. The ways different relationships are stored in the database is explained in the docs.

I strongly recommend using the GraphQL API to create various related documents and then use the dashboard to inspect what Indexes have been created for your schema and how the what the documents look like.

@wallslide @ptpaterson thanks for your assistance. I therefore worked through the GraphQL relations tutorial which is very clear.
However, I have come up against this issue as I attempt to graft the principles onto my own data.
Since I currently have no unique constraints defined in the schema or Fauna UI perhaps the problem relates to a tangential/deeper issue (?) …

I’ve replied. I do not think it’s a very deep issue. Just that when you update graphQL schema’s it doesn’t destroy any of the previous created Collections, Indexes, Functions, etc.

@wallslide @Jay-Fauna
I changed the schema section to:

type Player {
active: Boolean!
rank: Int!
ranking: Ranking! @relation
playerInfo: User @relation
challenger: Player @relation
}

and this schema successfully uploaded with the relevant indexes being created. I created the following e.g.:

mutation UpdateAPlayer {
updatePlayer(
id: "287857067752948225"
data: {
active: true
ranking: { connect: "282953512300577285" }
rank: 1
playerInfo: { connect: "283120055707763201" }
challenger: { connect: "287856474860814849" }
}
) {
_id
ranking {
_id
}
rank
playerInfo {
_id
}
challenger {
_id
}
}
}

I can use similar to createAPlayer (without a challenger) and above works to add a challenger. However, to remove the challenger (after a challenge has completed) I attempted to update without a challenger field (similar to create). This gave me:

"message": "An internal server error occurred. Please contact Fauna support."

Have I caused this by attempting an illegal operation?
Or is there some other reason for this error message?
thanks …

I reviewed this approach and believe I don’t want the playerInfo field because the User relation with challenger can provide all the necessary data alone. Schema is now back to:

type User {
active: Boolean!
username: String!
description: String
email: String
mobile: String
playedAs: [Player!]! @relation
}

type Player {
active: Boolean!
rank: Int!
ranking: Ranking! @relation
challenger: User @relation
}

type Ranking {
active: Boolean!
rankingname: String!
rankingdesc: String
player: Player @relation
}

type Mutation {
  createNewUser(active: Boolean!, username : String!, password : String!, description: String, email: String, mobile: String): loginResult! @resolver(name: "create_new_user")
  loginUser(username: String!, password: String!): loginResult! @resolver(name: "login_user")
}

type Query {
  allUserNames: [String!]! @resolver(name: "all_user_names")
  allPlayerUIDs: [String!]! @resolver(name: "all_player_uids")
  allPlayerRanks: [Int!]! @resolver(name: "all_player_ranks")
  allPlayerChallengerUIDs: [String!]! @resolver(name: "all_player_challenger_uids")
  allPlayers: [Player] @resolver(name: "all_players")
  allRankings: [Ranking] @resolver(name: "all_rankings")
  allUsers: [User] @resolver(name: "all_users")
  gotPlayersByRankingId (rankingid: String!): [Player] @resolver(name: "got_players_byrankingid")
  gotRankingIdsByPlayer (uid: String!): [String] @resolver(name: "got_rankings_byplayerid")
}

type loginResult @embedded
{
  token : String
  logginUser : User
}

and has been uploaded.
However, I created an index: players_by_member_ranking.
I have player doc:

{
"ref": Ref(Collection("Player"), "288025613763084801"),
"ts": 1610951808113000,
"data": {
"active": true,
"rank": 1,
"ranking": Ref(Collection("Ranking"), "282953512300577285"),
"challenger": Ref(Collection("User"), "283120055707763201")
}
}

When I query the Player collection by string ranking
“282953512300577285” I get:

No results found for the index "players_by_member_ranking"

This problem may be similar to a separate issue I posted in another thread.
Why are no results found if there is a ref to this ranking in the Player doc?
thanks …

You can/should use @index rather than @resolver if your just using an index with no other logic. In fact, fauna will generate the index for your based on your schema if you supply @index.

What you’ve done is point to a UDF function when you can use the index directly. This might simplify and resolve the latest issue.

@ptpaterson
The @resolvers are there because I followed this article closely.
I will anyway be requiring the security features for the app eventually and I believe the @resolvers are integral to the security setup (?).
This article was my introduction to Fauna and that approach was necessary as it needs to be compatible with Elm as my front end app is written in Elm.

  1. If I change @resolver to @index in the schema will I fix the current players_by_member_ranking issue, but disable the security setup?

  2. Or is there another/better way to conceive of/fix both of these issues?

Thanks …

Ok, that’s just fine what you are doing then. If you want more functionality wrapped around fetching the documents, that the right way to go, you’re doing well! :slightly_smiling_face:

You’ve not shared the FQL for the Index or the UDF, so it cannot be diagnosed directly. The UDF will of course receive just the id. Does the Index require the full Ref? So, are you providing the index the correct information?

If the term for the index is { field: ['data', 'ranking'] } then you need to provide it Ref(Collection("Ranking"), "282953512300577285"), not just "282953512300577285".

This from the other post, makes me think that the error might be from providing the wrong input for the term? But you’ll need to confirm how you are calling the Index.

You can test from the dashboard. But instead of using String as input, select FQL and type Ref(Collection("Ranking"), "282953512300577285") directly and hopefully you’ll see results for the index.

@ptpaterson
Yes, I was held up by the same issue in this thread and it has been resolved for retrieving a player list, at least. Thank you for your patient assistance and encouragement …

Very good!

The link you shared is to a page that says it’s private, so I can’t see it. But I am glad you got it working.