How to add auto increment to existing collection in mongodb/node.js? - javascript

Is there any methods or packages, that can help me add auto increments to existing collection? Internet full of information, about how to add AI before you create collection, but I did not find information on how to add AI when collection already exist...

MongoDB does not have an inbuilt auto-increment functionality.
Create a new collection to keep track of the last sequence value used for insertion:
db.createCollection("counter")
It will hold only one record as:
db.counter.insert({_id:"mySequence",seq_val:0})
Create a JavaScript function as:
function getNextSequenceVal(seq_id){
// find record with id seq_id and update the seq_val by +1
var sequenceDoc = db.counter.findAndModify({
query:{_id: seq_id},
update: {$inc:{seq_val:1}},
new:true
});
return sequenceDoc.seq_val;
}
To update all the already existing values in your existing collection, this should work (For the empty {}, you can place your conditions if you want to update some documents only):
db.myCollection.update({},
{$set:{'_id':getNextSequenceVal("mySequence")}},{multi:true})
Now you can insert new records into your existing collection as:
db.myCollection.insert({
"_id":getNextSequenceVal("mySequence"),
"name":"ABC"
})

MongoDB reserves the _id field in the top level of all documents as a primary key. _id must be unique, and always has an index with a unique constraint. It is an auto-incrementing field. However, it is possible to define your own auto-incrementing field following the tutorial in the MongoDB documentation.
Tutorial link: https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/

Related

How to pass own unique key in firebase and update it as well without destroying the structure?

I am currently trying to make a script where I pass my own unique key in firebase as primary key. It needs to work like this
StudentData
-Student Unique id
- referadID : "active",
- referadID2 : "inactive",
- referadID3 : "active",
-Student Unique id2
-referadIDnew : "active",
Here every student refers another student and once a refered student join that refered student who joined has his own unique id which stores value of active or inactive. The problem here is that if I use push it will generate a unique id which I don't want because it will make it difficult to work while using sorting. I don't want to do it. How can I create my own unique key in studentUniqueid2. I tried using transaction instead of push but the issue is that transaction instead of adding another key value pair would simply update the whole key leaving only the latest student unique id in the table which I don't want. Here is my code
let createData=adminDatabase.ref('/ReferralSystem/joinedtransactionlog');
createData.transaction(function(currentData){
if(currentData !== InviterId){
return {
[InviterId]: {
[member.id] : "active"
}
}
}else{
console.log("curretn data exists");
}
});
I am using javascript and working on firebase realtime database system with platform of Admin.
If I understand correctly, you have two UIDs: one for the inviter and the other for the invitee/member. In that case, you can write the structure in your question with:
createData.child(inviterUID).child(memberUID).set("active");
Doing this with a simple set operation will scale much better than the transaction you tried, since you're creating contention on the entire StudentData node while this merely performs an idempotent write.
There is no need to prevent writing the data if it already exists, as the operation is idempotent: subsequent writes don't change the result of the first write.

How to assign users to a group and sort them using firestore reference field type

I have a collection of employees that has data sent to it. Right now there is 4 employees but eventually there will be many more.
I want to add a grouping feature so that the user can sort the employees by their group. I am trying to find the best way to assign these employees groups and I found the reference field type in cloud firestore and thought I could use it to solve my problem. But I am stuck and not sure the most efficeient way to use it to link employees to a group.
This is my database. Right now I have the employees doc (ex. 2569) and inside that is a sub-collection with 2 documents in itself.
So end goal is to assign employees groups and then be able to sort and display them separately. Right now I have the group name assigned in articles/group -> groupName: "example".
(display them hopefully with ".Where( "groupName" "==" "example" ) somehow in code without hard-coding the group name. The group name will be created by the user so it could be anything)
Is what I am doing a good start? I know this question is a little odd but I am stuck and could really use some pointers on where to head next.
A collection group query would allow you to query all articles regardless of which employee contained them:
db.collectionGroup('articles')
.where('groupName', '==', 'X')
.get()
This would match documents in any collection (i.e. employees) where the last part of the collection path is articles. If you would like to find the employees who belong to a certain groupName, you may want to find the parent by retrieving the collection this DocumentReference belongs to.
Once you have the parent of the CollectionReference, you will get a reference to the containing DocumentReference of your subcollection.

How to increment a map value in a Firestore array

I have a firestore firebase database , in which I have a collection users
there is an array in the collection and in the array there is a map
in map there is a field qty.. I want to increment that qty value..
using increment doesnt help as the qty is inside a array index
db.collection("users").doc(checkId).update({
myCart: firebase.firestore.FieldValue.arrayUnion({
qty: firebase.firestore.FieldValue.increment(1),
}),
this is the error Output =>
Uncaught (in promise) FirebaseError: Function FieldValue.arrayUnion() called with invalid data. FieldValue.increment() can only be used with update() and set()
My answer below won't work, given that the qty is in an array. The only way to update an item in an array is to read the entire document, update the item in the array, and then write the entire array with the updated item back to the document.
An alternative would be to use a map instead of an array, and then update the qty using the approach outlined in my (old, and non-working) answer below 👇
You need to specify the full path to the field you're trying to update. So I think in your case, that'll be:
db.collection("users").doc(checkId).update({
"myCart.0.qty": firebase.firestore.FieldValue.increment(1)
}),
The field you want to update is embedded in an array. In this case, you can't use FieldValue.increment(), since it's not possible to call out an array element as a named field value.
What you'll have to do instead is read the entire document, modify the field in memory to contain what you want, and update the field back into the document. Also consider using a transaction for this if you need to update to be atomic.
(If the field wasn't part of an array, you could use FieldValue.increment().)
As of today (29-04-2020)... this is tested by me.
Suppose my data structure is like this:
collection: Users
Any document: say jdfhjksdhfw
It has a map like below
map name: UserPageVisits
map fields: field1,field2,field3 etc
Now we can increment the number field in the map like below:
mapname.field1 etc...
That is use the dot operator to access the fields inside the map just like you would do to an object of javascript.
JAVA Code (Android), update the field using transactions so they can complete atomically.
transaction.update(<documentreference object>,"UserPageVisits.field1",FieldValue.increment(1));
I have just pushed a version of my app which uses this concept and it's working.
Kudos !!
My Best Regards
Previous answers helped me as well, but dont forget about the "merge" property!!! Otherwise it will overwrite your entire array, losing other fields.
var myIndex = 0;
const userRef = db.collection('users').doc(checkId);
return userRef.update({
'myCart.${myIndex}.qty': admin.firestore.FieldValue.increment(1)
}, {
merge: true
});

Incrementing index in mongo db

When adding a field called date in mongo db, I can do just:
date: {
type: Date,
default: Date.now
}
and it will automatically add date field to my new collection when it was created. Is there some way to add a self-incrementing index (id) to my collections?
Note: I tried to do it on client side, however with every time I push collection with (id) field, its being deleted from the collection and replaced with _id which is a long string with random characters. Way to long!
Looking for every hints.
Edit: code responsible for adding use to db
app.post("/users", function (req, res) {
createUser(req.body, function (err, user) {
if (err) {
return res.json(err);
}
return res.json(user);
});
});
MongoDB automatically makes unique ids for each object in the database, resulting in each entry having a unique _id field being an ObjectId. You don't really need to worry about specifying custom ids.
You can sort by _id if you want objects roughly in the order they were created, or you could add a date field which is set on creation and sort by that.
Other than that, I'm not sure what you'd gain by having auto incrementing ids
There are multiple ways to implement an auto-increment index but it is not considered a good practice.
Detailed information here: Auto increment in MongoDB to store sequence of Unique User ID
Check Rizwan Siddiquee answer about how to implement it with a stored javascript function.
Another way would be to implement it on application layer using any kind of ODM but this is obviously dangerous and not so trustable for serious applications.

Correct way to model a collection of items in Firebase

In the docs I see a lot of examples using index values as a part of the key name for a particular item --- but I don't understand how this is a consistent way to model your data.
For example let's say I have a list of articles:
https://gigablox.firebaseio.com/articles/
article1
article2
article3
When I'm ready to add article4 I know I can use:
var length = Object.keys($scope.articles).length;
And using AngularFire 0.5.0 I can save it with:
var name = 'article' + length + 1;
$scope.articles[name] = $scope.article;
$scope.articles.$save(name);
But what happens if I:
$scope.articles.$remove('article2');
And add another record using the same approach? We're likely to create duplicate key names.
To add a little complexity, let's add a single relationship and say that each article has comments.
What is the correct way to model this data in a Firebase collection?
Please use $add and let Firebase automatically generate chronologically ordered lists for you.
var ref = new Firebase("https://gigablox.firebaseio.com/articles/");
$scope.articles = $firebase(ref);
$scope.addArticle = function() {
$scope.articles.$add($scope.article);
}
$scope.removeArticle = function(id) {
$scope.articles.$remove(id);
}
Firebase automatically creates key names when you call $add. You can iterate over the key names using ng-repeat:
<div ng-repeat="(key, article) in articles">
<div ng-model="article"><a ng-click="removeArticle(key)">Remove</a></div>
</div>
EDIT: You should follow the suggestion from #Anant if you want an array-based collection.
However, for this specific scenario as outlined by #Dan Kanze, if you want to pull the key out of the URL (as would be done for a content management system, etc), you should generate your own keys unique to the content. For example, if you know that article names need to be unique, create a slug function that will:
Lowercase the article name
Replace spaces with underscores
etc..
If the article name changes, you would not delete the old entry. Instead, create a new entry in Firebase and use the old key to point to the new location for 301 redirects, etc.

Categories

Resources