This code won't work, I got error of E11000 duplicate key error index error.
Student.update({_id: id, 'data.date':date}, {'$set': {'data.score': 50}}, {upsert: true},
function(err,result) {
res.json(1);
});
I have no clue how to solve it when I can do
Student.findOne({_id: id}, function(err,result){
res.json(result)
})
Any clue what's going on?
I see two possible problems:
You may have set some of the fields as unique and Mongo created an index for that field. For example if data.score would be unique then you couldn't have two documents with the same value and maybe other document already has a value of 50.
The solution would be to search for indexes and remove the ones that you don't want.
Maybe your search for {_id: id, 'data.date': date} doesn't return a result but not because you don't have a document with that id, but because it doesn't have that 'data.date' field that you search for. Then the upsert tries to insert a new document (because the search didn't find anything that has both '_id' equal to id and 'data.date' equal to date) but it fails to do so (because you already have a document with '_id' equal to id).
The solution would be to search only by _id if you're using upsert.
Related
I have a collection of documents like this:
{
uid: <UNIQUE_USER_ID>,
lastLoggedIn: <TIMESTAMP_IN_NUMBER>,
...
}
when I try to fetch the data using:
Server.db
.collection(firebasePaths.funfuse_verified_users)
.where('uid', 'not-in', notToIncludeAccounts)
.orderBy('lastLoggedIn', 'desc')
.startAt(startAt)
.limit(limit)
I get an error saying:
Error: 3 INVALID_ARGUMENT: inequality filter property and first sort order must be the same: uid
and lastLoggedIn
Is this a known limitation of firebase or am I doing something wrong ? I want to query all the users which aren't in an array using not-in and then sort those results based on lastLoggedIn timestamp activity.
As the error message says, in order to be able to use not-in you must first order on the same field:
Server.db
.collection(firebasePaths.funfuse_verified_users)
.orderBy('uid')
.where('uid', 'not-in', notToIncludeAccounts)
.orderBy('lastLoggedIn', 'desc')
.startAt(startAt)
.limit(limit)
This also means that the results will be order first on uid and only then (so if there are multiple results with the same uid value) on lastLoggedIn. If you need them in another order, you will have to resort them in your application code.
I have a quick question about mongoose schema real quick. Here is the code: https://i.ibb.co/Db8xPMw/5555.png
I tried to create a document without the property "work". It works in the first time, but it didn't start to work on the second time that I do the same thing again.
Do you have any idea?
Basically I create two documents without an "work" property, which causes a duplicate key error. However, I didn't set up unqiue: true though.
Error :
"errmsg" : "E11000 duplicate key error collection: test.user index work_1 dup key: { : null }
From the message it says your collection has an index with name work_1 probably on field work, Since you've created a document without work field then basically you cannot create another document without work field what so ever in the same collection, cause two documents with no work field or even work field with value as null or same cannot exist as it violates unique constraint policies (it says dup key : { : null}) !! Uniques indexes can be created via mongoose schemas or can also be created by manually running queries on database.
Ref : Search for Unique Index and Missing Field in index-unique
So you need to drop the existing index using dropIndex & then if needed recreate it using createIndex. MongoDB would automatically convert a created index to index-multikey (multi-key index - indexes on array fields) if at least one existing document has array value for that indexed field by the time you create index or even if an array value gets inserted for that field in future.
Through code - Drop index : yourSchema.dropIndex({yourFieldName: 1}) && Create index : yourSchema.index({yourFieldName : 1})
NOTE : Just in case if you want to have certain criteria in unique indexes like situation from this question where indexed field can be missing in some documents but it shouldn't be considered as duplicate insertion, then you can take use of partial-indexes (Search for Partial Index with Unique Constraint) which would only index documents where work field exists.
Ex of partial-indexes :-
db.yourCollectionName.createIndex(
{ work: 1 },
{ unique: true, partialFilterExpression: { work: { $exists: true } } }
)
Ref : mongoose-Indexes
My documents have the key order, which is an ascending numeric value.
Now I would like to get the highest order value of all documents which has a specific parent value.
What I am doing is (I'm using mongo native driver)
find all documents with the specific parent id
sort the result in descending order
limit to 1 document
I'm doing this, as I think findOne can't sort the documents. Am I right with that?
const last = await Content.find({ parent: parentID }).sort({ order: -1 }).limit(1).toArray()
console.log(last[0].order)
Now I get an array with a single document. But is it possible to get only the document itself without returning the result as an array?
You want to use findOne like this:
var options = {
"sort": [['order','desc']]
};
Content.findOne({ parent: parentID }, options, function(err, result) {
if (err) throw err;
console.log(result);
});
I have made a mistake naming subcollection in MongoDB, unfortunately I named them using hyphen :/
Here is sample :
{
id: "..."
"A-Section": {
"val":1
}
}
I need to access the "val" field. Unfortunately hyphens seems to block MongoDB.
So I have to option :
Find a trick to access the "A-Section"
Rename all the "A-Section"
In both case I do not know how to do it and after few researches, I only found answer if the collection name contains hyphen but not a subcollection.
The database contains collections of documents, each document has it's own key-value pairs.
I assume you ment renaming a field in the collection and not an array inside a field.
So you can use the $rename operator to rename all fields in the collection
ex:
db.collectionName.update( {"A-Section": {$exists:true}}, {$rename: {"A-Section": 'ASection'} }, {multi: true} )
I'm trying use find function to get data from my DB in mLab. I wrote this code, but I am getting an empty string.
My schema had id, name, course and grade.
It works for me when I want the file of the name but not for id. I guess it's because of the extra _id files that the mLab adds.
How do I fix it to get back the JSON that fits the id (let's say id=1)?
app.get('/getStudentById/:id', function(req, res) { //else if url path is getStudGrade with id param
Stud.find({id:req.params.id}, function(err, user){
if(err) throw err;
res.json(user);
mongoose.disconnect();
});
})
new edit
I have changed the filed 'id' to 'idStudent' in my DB and now it working.
Stud.find({ idStudent: req.params.id)}...)
but why?
So, assuming req.params.id actually has a value and /getAll shows that all your records have an id field set, the only thing that jumps out to me is the fact that your comparing a string to a Number i.e. req.params.id will be a string after deserialization but your schema dictates that the id field is numeric.
I am not sure if mongoose uses coercive comparison i.e. == over === (I doubt it), so in order to be more accurate you should parse your string to Number then do the comparison e.g.
Stud.find({ id: parseInt(req.params.id)}, ...)
Functions in query clause might not work, so to convert to Number just do:
Stud.find({ id: 1*req.params.id}, ...)