Rollback / Un-delete documents in FaunaDB - faunadb

In FaunaDB, I would like to:
Un-delete a document
List deleted documents by collection
How would I go about doing this?

You would need to Remove() the "delete" event of that document.
Remove(docRef, timestamp, "delete")
In order to know the timestamp of those events, you can Paginate() for the Events() of that document and get that info, assuming your document was not garbage-collected:
Paginate(Events(docRef))
You would need an index that covers the references of your documents, and then you can Paginate() for the Events() of that index and filter for "remove" actions. Let's assume you have the index "all_posts":
Filter(
Paginate(Events(Match(Index("all_posts")))),
event => Equals("remove", Select("action", event))
)

Related

How can I query data from FaunaDb if only some collections have a specific property which I need to filter out

I'm really new to FaunaDb, and I currently have a collection of Users and an Index from that collection: (users_waitlist) that has fewer fields.
When a new User is created, the "waitlist_meta" property is an empty array initially, and when that User gets updated to join the waitlist, a new field is added to the User's waitlist_meta array.
Now, I'm trying to get only the collections that contain the added item to the waitlist_meta array (which by the way, is a ref to another index (products)). In a other words: if the array contains items, then return the collection/index
How can I achieve this? By running this query:
Paginate(Match(Index('users_waitlist')))
Obviously, I'm still getting all collections with the empty array (waitlist_meta: [])
Thanks in advance
you need to add terms to your index, which are explained briefly here.
the way I find it useful to conceptualise this is that when you add terms to an index, it's partitioned into separate buckets so that later when you match that index with a specific term, the results from that particular bucket are returned.
it's a slightly more complicated case here because you need to transform your actual field (the actual value of waitlist_meta) into something else (is waitlist_meta defined or not?) - in fauna this is called a binding. you need something along the lines of:
CreateIndex({
"name": "users_by_is_on_waitlist",
"source": [{
"collection": Collection("users"),
"fields": {
"isOnWaitlist": Query(Lambda("doc", ContainsPath(["data", "waitlist_meta"], Var("doc"))))
}
}],
"terms": [{
"binding": "isOnWaitlist"
}]
})
what this binding does is run a Lambda for each document in the collection to compute a property based on the document's fields, in our case here it's isOnWaitlist, which is defined by whether or not the document contains the field waitlist_meta. we then add this binding as a term to the index, meaning we can later query the index with:
Paginate(Match("users_by_is_on_waitlist", true))
where true here is the single term for our index (it could be an array if our index had multiple terms). this query should now return all the users that have been added to the waitlist!

firestore remove documents by field value

each of my docs in my firestore db contains 1 field {name: 'some value'}
I would like to loop through all the docs and then if the doc's fields value is equal to my param I would like to remove that doc
I'm trying to do it like so:
removeContact: function(name){
console.log('removing contact',name)
db.collection("contacts").forEach(doc=>{
if(doc.data().name === name){
doc.delete()
}
})
}
but I get the error that forEach() is not defined.
You need to use .get() following the collection or query to get a query snapshot promise, which you then handle accordingly. You can use forEach on the snapshot and delete each doc.
A better way, instead of searching through every document and using an if statement, would be to use a query like where('name', '==', name) and delete the document that way. Using a query would leave less for your function to do.
To delete a document, you need to know the full path to that document. And since you don't know the document IDs, that means you'll first need to read the documents.
The good news is that this means you can also perform a query to filter only the documents you're interesting in, instead of doing an client-side if.
db.collection("contacts").where("name", "==", name)
.get()
.then((querySnapshot) => {
querySnapshot.forEach(doc=>{
doc.ref.delete()
})
})

transforming foreign constraints in raven document db

I have following entity "MyEntity" in my RavenDb
{
Id: {Guid}
//...
//...
}
In the application there might occur a specific event relating to elements of MyEntity.
Not I want to associate users (also in db of course) with this type of event in order to allow the eventhandler to handle the event only if there is a relation between MyEntity and User
Using MySQL I'd create a table which which aggregates MyEntity.Id with User.Id (and possibly a specific EventId) 1:x (x element N) so that I can query all items with a a specific Id (MyEntitiy.Id) and the corresponding User.Id
Is it okay to simply apply this approach to a document db like RavenDb? Or should I consider something else?
Relations between documents in RavenDB is implemented in the following way:
A document can reference any other document from the database by storing the referenced document ID in the document. Referenced documents are called: Related Documents.
For example, document employees/3-A is referring to document employees/2-A:
{
"LastName": "Leverling",
"FirstName": "Janet",
"ReportsTo": "employees/2-A",
}
These related documents can be 'loaded', 'indexed' & 'queried on'.
Learn more about document Modeling & working with multiple documents in the following links:
Document Modeling
Working with multiple documents
Handle Document Relationships

In RavenDB can I retrieve all document Id's for a document type

My Scenario:
I have a few thousand documents that I want alter (rename & add properties), I have written a a PatchRequest to alter the document but this takes a document Id.
I'm looking for a way to get a list of document Id's for all documents of a specific type, any ideas?
If possible I'd like to avoid retrieving the document from the server.
I have written a PatchRequest to alter the document but this takes a document Id.
No, .Patch takes a document ID, not the PatchRequest.
Since you want to update a whole swath of documents, you'll want to use the .UpdateByIndex method:
documentStore.DatabaseCommands.UpdateByIndex("IndexName",
new IndexQuery {Query = "Title:RavenDB"},
new []
{
new PatchRequest
{
Type = PatchCommandType.Add,
Name = "Comments",
Value = "New automatic comment we added programmatically"
}
}, allowStale: false);
This will allow you to patch all documents matching an index. That index can be whatever you please.
For more information, see Set-Based Operations in the Raven docs.

How to write a RavenDB index as a prefiltered list of documents, not searchable

I want to get a list of users filtered by a property (string) being null or empty.
I've created an index for this but I'm not sure if my way of implementing it is the right way to do it.
public class Users_Contributors : AbstractIndexCreationTask<User>
{
public Users_Contributors()
{
Map = users => from user in users
where user.ContributionDescription != null && user.ContributionDescription != ""
select new {};
}
}
So I just want raven to "prepare" the list of users for me. I'm just gonna get all user objects out of that index with no additional filtering/where criterias at query time.
Is the above code the way to go or can I achieve the same in a better way? Im feeling Im missing something here. Thanks!
This will work just fine. The result would be that the index only contains users that have something in their ContributionDescription field.
If you want to make it slightly easier to read, you can use string.IsNullOrEmpty, but that won't have any impact on performance.
Map = users => from user in users
where !string.IsNullOrEmpty(user.ContributionDescription)
select new {};
It probably feels strange because of the empty object at the end, but that just defines the index entries. If you aren't sorting or filtering by any other field, then using an empty object is just fine. Keep in mind that the __document_id entry gets created regardless of what fields you map.