I have document which I need to update but updated parameters are not same all the time it depends on user. So how can I update document or replace whole document with new values based on id.
You wrap your updated values in a Map the set the update:
Map<String, Object> updateInfo; // Key is db column name, value is updatedValue
Then create update operations:
Query<Entity> filter = datastore.createQuery(Entity.class)
.field("_id", id);
UpdateOperations<Entity> updateOps = datastore.createUpdateOperations(Entity.class);
updateInfo.entrySet().forEach(e -> updateOps.set(e.getKey(), e.getValue());
datastore.update(filter, updateOps);
By this way, you can update entity with any number of fields
Related
Here's my Firebase database
Within the "users" collection, I have a document "xyz#gmai.com. The document has an array "status". I'm trying to update one of the elements in the "status" array.
I've written the following but I would like to understand if I need to write a separate query to delete first or would this actually update the existing record or add a new record in the "status" array with the same id (1)
final conn = FirebaseFirestore.instance.collection("users")
.doc(email);
conn.update({
"status": FieldValue.arrayUnion([{
"date":"10/15/2022",
"id":1
}]),
});
In general, instead of update you can use set with option merge: true to change only the fields you specify and leave the others alone:
conn.set({'field': 'newValue'}, SetOptions(merge: true));
But in your case the code that you have written will always add a new element to the array status with the new data even if the id already exists.
One solution is to go through the existing elements in status array and update if you find the id or add a new element.
The other solution is to create a subcollection status and use set with the id. In this case Firestore will do the job and either create a new document or update the existing:
conn.collection('status').doc(1).set({'date': '10/15/2022'});
In both cases please remember that these operations are async so you might want to use await.
I had to delete and add the new entry. It's very inefficient compared to how we do things in a traditional database i.e SQL UPDATE. Network calls are expensive and should be avoided. I like Peter Koltai's approach but that would force me to refactor my schema which I can't.
Future<void> updateReqStatus(email, id, oldDate, newDate) async {
final conn = FirebaseFirestore.instance.collection("users")
.doc(email);
conn.update({
"status": FieldValue.arrayRemove([{
"date":oldDate,
"id":id
}]),
}).then((value) => print("value"));
conn.update({
"status": FieldValue.arrayUnion([{
"date":newDate,
"id":id
}]),
}).then((value) => print("value"));
}
I'm using Swift here and confused about how to save the document ID into itself field. Here is an example :
I have a collection named "menu"
here we can focus on the one and only document in the "menu" collection which saved the name field "ayam goreng". How do i save the document ID "
7D3fuw3fri6oj287SySW" to the field named "menu_id" inside the document?
As shown in the documentation on adding a document:
In some cases, it can be useful to create a document reference with an auto-generated ID, then use the reference later. For this use case, you can call doc():
let newCityRef = db.collection("cities").document()
// later...
newCityRef.setData([
// ...
])
In your case, you can then get the document ID from the new ref with:
newCityRef.documentId
I wish to generate a scatter plot using time on the x-axis from user generated submissions. To do so I am making a list of maps in which each map is the user submission and contains a timestamp field. The issue is that I cannot add a timestamp using the arrayUnion. This issue was mentioned in this post:
Link1
You can't use FieldValue.serverTimestamp() as the value to union (add) or >remove, to or from, an array type value of a document field. If you want to >use that timestamp value, you need to pass it directly to a field you're >updating or setting.
So,to solve my problem I need to update directly the field for timestamp after I have already added some data which has a form similar to below and I only need to add to the last element/Map of my List/array of Maps but I do not know how long this list currently is:
myList[{Map1}{Map2}{Map3}...{examplefield:'Some data', timstamp:null}]
final Map submissionMap = submissionData.toMap();
//Running a firestore transaction...
final DocumentReference areaDocument = Firestore.instance.document('Space/SAJJEED');
Firestore.instance.runTransaction((Transaction tx) async {
DocumentSnapshot postSnapshot = await tx.get(areaDocument);
if (postSnapshot.exists) {
//Adds the data except for the timestamp needed
await tx.update(areaDocument, <String, dynamic>{'$status': FieldValue.arrayUnion([submissionMap])});
//Insert Code for directly accessing the timestamp field and adding Timestamp
}
});```
Any other workarounds would be appreciated as well.
I want to update 10,000 documents in a single web request. I intend to update only one field (which is indexed) in all the documents matched with some criteria with same value.
I see morphia 1.3.2 always set multi=true parameter in update call. Is it enough for updating 10,000 document? Or there are any bulk update functionality in morphia.
The following code should work for you.
Query<Entity> query = datastore.createQuery(Entity.class);
query.filter("name = ", "xxx");
UpdateOperations<Entity> updateOperations = datastore.createUpdateOperations(Entity.class).set
("yyy", 200);
UpdateResults updateResults = datastore.update(query, updateOperations, false, null);
All the documents in the collection with name = 'xxx' will now have all their 'yyy' attribute equal to 200.
How can I update a field with the value of other field?
For example, I want to update the field updated_at with the value of the field created_at (it's like cloning fields)
$dm->createQueryBuilder('MyBundle:MyService')
->update()
->multiple(true)
->field('updated_at')->set(CREATED_AT_ATRIBUTE)
->getQuery()
->execute();
Thanks
Option #1: Application side update
The easiest approach when using Doctrine ODM is to perform the update on the application side. So you fetch all the objects you want to update, make the necessary adjustments and flush them.
$services = $dm->createQueryBuilder('MyBundle:MyService')
->getQuery()
->execute();
foreach ($services as $service) {
$service->setUpdatedAt($service->getCreatedAt());
}
$db->flush();
$services represents the mongo cursor, which will fetch the documents as you iterate. You can set eagerCursor to true if you want to fetch all the documents from the collection at once.
Option #2: Database side update
You can also perform the update directly on the database itself. To do so however, you'll need to create the query yourself as the query builder doesn't support this functionality.
// Get MongoDB instance from DocumentManager
$mongo = $dm->getDocumentDatabase('Fully/Qualified/Class/Name')
->getMongoDB();
// Iterate over the collection and update each document
$mongo->execute('
db.MyServiceCollection.find().forEach(function (item) {
db.MyServiceCollection.update(
{_id: item._id},
{$set: {updated_at: item.created_at}}
);
});
');
The function used in forEach is just a regular javascript function, so you can insert some more logic in there if you need more control over what you update.