0

I am new to firestore as well as NoSQL. I want to make a simple database which is somewhat relational, with two tables, In terms of relational databases, one is operational (patients) and one is a transactional (readings) table.

I have an app that generates data for a patients table and a readings table. One app instance may contain data of many unique patients and each patients may have different readings in the readings table.

In Firestore I plan to achieve this by making two collections, for each of the tables mentioned and bulk upload documents for each patient and reading in the corresponding collection. Now every time I do a bulk upload to the firestore, I want to check if all the fields in the input patient JSONObjects exist in the patient collection than pick up the patientID else, make a new patient, and generate an ID and enter the reading with the given patientID.

I tried to do this with transactions but that only works for a single document, as mentioned here, (Can we not query collections inside transactions?) With Batch only set(), update() and delete() operations are possible as mention in the documentation, with batchget too we can only search using the document ID and not the fields.

Is there any way I can do this, are there any issues with the schema?

Mital Pattni
  • 1
  • 1
  • 1
  • Please provide one or two example records. What is the uniquely identifying field for a patient? One idea for schema is a collection with doc ids derived from a unique patient property and readings is a sub-collection of patient. – danh Sep 01 '20 at 23:03
  • All patient fields are supposed to be unique. Actually my main concern is updating the patient collection without any duplicates. – Mital Pattni Sep 05 '20 at 10:41

1 Answers1

0

Indeed, trying to batch read data from your collection and then, updating it, won't be possible directly. As clarified in this other similar case here, you can read up to 10 documents at once, using IN to fetch multiple documents, however it's not very feasible.

The best for you to do it, without changing your scheme, would be to read the collection entirely with a forEach() and then, perform a batch update from specific documents, based in the id that you return. This way, for example, with the patientId, you should be able to update all the readings. The below code show to perform the batch, once you have the id.

DocumentReference patRef = db.collection("patients").document("id");
batch.update(patRef, "Value1", "Value2"); //Update two sample of fields in the document

batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        // ...
    }
});

The other option would be to work with Subcollections, so you can have all your data stored in one father collections and it subcollections. This way, you can deal with everything within one query, which for sure, would make your work easier.

I would say that the second one is better, however, involves restructuring your scheme. The good part is that once you have done it, your work will be much easier.

gso_gabriel
  • 4,199
  • 1
  • 10
  • 22