The ‘d’ property is a variable.
[ ].map((d => .. do something ... )
q.Map(, q.Lambda(['d'], Var('d') )
If you apply that on you map. Var(‘d’) will be equal to one of your objects in the array, for example:
PS: you do not have to abstract the FQL away in that function. You could just place the whole upsert function in the Map directly but I wanted to show you what you could do to keep it clean :). E.g.
Just to be clear towards other users who might read this. There are no immediate plans to support SQL as our roadmap surveys have suggested low interest in SQL. This is a question that often comes back due to an announcement that was released a while back. The roadmap surveys came right after that and showed low interest, hence SQL has been deprioritized.
That said, there are reasons that FQL is what it is. FaunaDB is a massive scalable database that’s also pay-as-you-go. I personally had experience with NoSQL databases being queried by an inexperienced person (e.g. for analytics purposes) which resulted in crashes of nodes. The ex-twitter engineers who designed FQL had similar experiences and FQL was built to avoid specific pain points. For the people who are interested why it’s so different I’ll quickly write down a few points.
It’s not declarative, due to the following reasons:
Query is the query plan: a declarative query has to be interpreted and an optimal query plan has to be constructed. In data heavy applications, it often happens that your query plan looks good at a certain time and when your data grows, the query plan changes and you suddenly get a performance bottleneck. In traditional databases you declare what data you want to see and the query planner will attempt to come up with an intelligent query plan. That intelligent plan might not be so intelligent. In FQL you define exactly how your data should be fetched so there are no surprises.
Mandatory indexes: Indexes are mandatory to avoid shooting yourself in the foot. That is much easier to support when you explicitly define the query plan (e.g. in FQL the query is the query plan).
One language for querying/security/functions In SQL you typically have stored procedures which are a different language (e.g. PL/SQL) than SQL in order to support conditional logic etc more easily, a language which is not super easy either. In FaunaDB, FQL can do everything in the same language, User Defined Functions, Security Roles (ABAC) are all written in the same language.
FQL is meant to fetch or do everything in one query: the same principle as GraphQL, instead of doing multiple queries, FQL is designed to do everything in one query, things that are sometimes feasible in SQL yet become very difficult if your query becomes more complex. Especially if a part of that query is to update something depending on conditional logic.
FQL is meant to support business logic: having business logic close to the data makes sense since you can then benefit from the strong consistency of your data. FQL Is meant to be able to express business logic as well.
As we have shown above you can easily create your own Upsert function, and once someone has done that and placed it in a library, you can’t even see the difference (given that we follow the same naming conventions) between FQL and that new function. It’s arguably not very difficult to then write the query:
myUpsertFunction( < some data > )
or apply it on a list:
Map(< some data in array > , Lambda(['d'], myUpsertFunction(Var('d'))))
To be clear, I respect your points of view and we get it, FQL has to become less verbose in the future and more high-level. I just want to make sure that you can see the potential and good parts of it as well