Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I update a FaunaDB document without knowing its ID?

Tags:

faunadb

FaunaDB's documentation covers how to update a document, but their example assumes that I'll have the id to pass into Ref:

Ref(schema_ref, id)
client.query(
  q.Update(
    q.Ref(q.Collection('posts'), '192903209792046592'),
    { data: { text: "Example" },
  )
)

However, I'm wondering if it's possible to update a document without knowing its id. For instance, if I have a collection of users, can I find a user by their email, and then update their record? I've tried this, but Fauna returns a 400 (Database Ref expected, String provided):

client
  .query(
    q.Update(
      q.Match(
        q.Index("users_by_email", "[email protected]")
      ),
      { name: "Em" }
    )
  )
like image 811
Em. Avatar asked Mar 09 '20 04:03

Em.


2 Answers

Although Bens comments are correct, (that's the way you do it), I wanted to note that the error you are receiving is because you are missing a bracket here: "users_by_email"), "[email protected]"

The error is logical if you know that Index takes an optional database reference as second argument.

To clarify what Ben said: If you do this you'll get another error:

Update(
  Match(
    Index("accounts_by_email"), "[email protected]"
  ),
  { data: { email: "[email protected]"} }
)

Since Match could potentially return more then one element. It returns a set of references called a SetRef. Think of setrefs as lists that are not materialized yet. If you are certain there is only one match for that e-mail (e.g. if you set a uniqueness constraint) you can materialize it using Paginate or Get: Get:

Update(
  Select(['ref'], Get(Match(
      Index("accounts_by_email"), "[email protected]"
  ))),
  { data: { email: '[email protected]'} }
)

The Get returns the complete document, we need to specify that we require the ref with Select(['ref']..

Paginate:

Update(
  Select(['data', 0], 
    Paginate(Match(
      Index("accounts_by_email"), "[email protected]"
    ))
  ),
  { data: { email: "[email protected]"} }
)
like image 148
Brecht De Rooms Avatar answered Mar 24 '23 19:03

Brecht De Rooms


You are very close! Update does require a ref. You can get one via your index though. Assuming your index has a default values setting (i.e. paging a match returns a page of refs) and you are confident that the there is a single match or the first match is the one you want then you can do Select(["ref"], Get(Match(Index("users_by_email"), "[email protected]"))) to transform your set ref to a document ref. This can then be passed into update (or to any other function that wants a document ref, like Delete).

like image 39
benjumanji Avatar answered Mar 24 '23 19:03

benjumanji