Suppose this scenario.
I have a collection where I store products, this products have a property called "props" and this is an array of objects, that have properties like measure, weight.
The problem comes when I'm trying to insert new products. I'm receiving an array of objects that will be inserted, but each element of the array could have a property called "propsReference", and If it's there, it would be an ID that refers to the object that's currently inserted and have some props
So, if it has the propsReference property with an ID, I want to copy the properties of this object to the object I'm going to insert
The only solution I can think of is doing a foreach to the first array, if it has the propsReference do a query, get the props and insert it into this element of the array as a new property of the object.
But I'm having a lot of problems with doing queries inside a for loop, there's any way in mongoose or something to avoid that?
Thanks in advance
Related
I would like to update the completed property of an object in an array in Firestore, but I have no idea how to reach that specific element in the array. The image will show the structure.
I have come up this far but don't know how to choose, for example, item 1 in the array. I was thinking of using its ID (it has an id property) but don't know how to get there.
const businessRef = db.collection('approvedBusinesses').doc(businessId)
try {
businessRef.update({
[`bookings.${currentDate} ????? `]: true // what to add after currentDate?
})
By the way, this is how the array was created (and how other objects are pushed to it)
const bookingObj = {
carro: 'PASSA_CARRO',
completed: false,
userId: userObject.uid,
}
businessRef.update({
[`bookings.${currentDate}`]: firebase.firestore.FieldValue.arrayUnion(bookingObj),
})
Firestore does not have an operation that allows you to update an existing item in an array by its index.
To update an existing item in the array, you will need to:
Read the entire document into your application.
Modify the item in the array in your application code.
Write back the entire array to the document.
I'm pretty sure this has been asked before, so let me see if there's an answer with an example.
Also see:
How to remove an array element according to an especific key number?
Simple task list ordering - how to save it to Firebase Firestore?
How to update only a single value in an array
How to update an "array of objects" with Firestore?
i've been googling around about how to add an object into an array in firestore, and found the arrayUnion() able to add an object into firestore array, but it only add the object into last index of array, but how to add it into first index of array?
//add "greater_virginia" into last index of array
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});
//how to add "greater_virginia" into first index of array?
its basically same as arrayUnion but instead of add it into last index, i want to add it into first index of array.
If Firestore arrays behave anything like realtime-database arrays, then they don't actually exist. As far as I know, they are store as maps, like:
{
0: "first element",
2: "second and so on",
}
You can probably see how an unshift would be a big transformation. In fact, firestore doesn't let you do this, saying "...in order to avoid some of the issues that can arise in a multi-user environment, you'll be adding them with more of a set-like functionality".
With that in mind, this problem is usually solved at the application level by fetching the array, mutating it as needed, then setting the whole thing.
Bit of further reading https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html
PS: be careful with the arrayUnion operator, because it actually performs a add to set
Firestore doesn't offer any way to modify items of array fields by index. arrayUnion will only ever append to the end of the array if the element doesn't already exist.
If you want to modify an array by index, you will have to read the document, modify the array in memory to appear how you want, then write the modified array back to the document.
While going through the docs encountered these lines on linkingObjects properties please explain them:
"When accessing linkingObjects properties, a Results object is
returned, so further querying and sorting are fully supported.
linkingObject properties belong to the object they were acquired from
and can not be set or manipulated directly. They are updated
automatically when a transaction is committed."
#LinkingObjects is an inverse relationship 0...* that can be automatically evaluated when an object has a 0...1 or 0...* relation to another table.
So when A has a property cats to RealmList<Cat>, then Cat table can have linking objects property to A via linkingObjects("cats"), which is a RealmResults<A>.
What it says however is that you cannot remove items directly from linking objects because it is a computed property, items are only removed from linking objects if the item is removed from the not-inverse relation (the list), or the item is deleted.
When an item is deleted in a transaction, removal of item from linking objects is immediate.
In my Meteor app, I already have a collection fullList = new Mongo.Collection('fullList'); that is an array of objects, and each object has several attributes, such as Color, Factor, and Tot.
I want to create a new collection - or at least just a new array - that is, an array of all of the Tot values. The pseudo-code would be something like newList = fullList.Color, if that makes sense.
I know how to display one attribute in html using {{Color}}, but I can't seem to do anything with it in JavaScript.
In case it's relevant, the reason I want this array is I'd like to use D3.js to represent that data.
It sounds like your collection is a set of documents (in Mongo terminology), with each document being a serialised object, rather than actually a single-document collection that stores an array. In that case, you should be able to use the built-in map function on your collection cursor. Documentation here:
http://docs.meteor.com/#/full/map
This would look something like (using only the document argument in the callback):
fullList = new Mongo.Collection('fullList');
newlist = fullList.find().map(function(document) {
return document.Tot;
});
map() will iterate over all the documents in the collection - as no arguments are passed to find() - and for each document add an item to an array (assigned to newList) that is the value returned by the callback function, in this case Tot.
I have an IndexedDB of changes. I add an item like this, and then log the result to check the key has been created successfully:
_this._idb.add('steps', step).done(function (items) {
var item = items[0];
_logger.log("ADDED STEP", { id: item.__id__, step: item }, "CT");
});
The output from this is as expected:
...as you can see, the id has been added to the object when it is stored.
However, when I query the db to getback a list of objects, using this code:
this._idb.steps.query('timestamp').bound(start, end).execute().done(function (results) {
_logger.log("Results", results, "CT");
}
I don't get the id as part of the object that is returned:
... and the lack of id makes updating and deleting impossible.
How can I get the id of the item when I query indexed db using db.js - or am I approaching this in the wrong way, and is there something else I should be doing?
(Note: I'm using TypeScript to compile the JS, but I don't think that's especially relevant to this question)
This is expected behaviour, you're only going to get the __id__ property if you don't define a keyPath in your db schema.
Because there's no keyPath defined the value is not associated with it in indexeddb, it's only added to the resulting object after it has been added, because at that point in time we know the auto-incremented value that IndexedDB has assigned to it.
Since the value isn't really part of the object I don't have any way to assign it to the object when it comes out during a query, maybe I could use the position in the array but that's more likely to be wrong than right.
If you want the ID to be persisted against the object then you need to define a keyPath as part of the object store schema and the property will be added to the resulting object and available and it will be on the object returned from a query.
Disclaimer - I wrote db.js
Looking at the source, __id__ is only defined when your keyPath is null in the add() method. From what I'm seeing, you'll never see this in a query() response.
In IDB null keyPaths are allowed only when using auto-incrementing ("out-of-line") keys. So if you're getting the object back, it should have an auto-incrementing key on it or some other keyPath.
The __ prefix in JavaScript usually means the developer intended it to be a "private" property. I'm guessing this is for internal use and you shouldn't be counting on this in your application code.
Consider using explicit, so-called "in-line" keys on your object store.
The goal of db.js is easy and simple to use. Your is advanced use case.