Argument passed in must be a single String of 12 bytes - node.js

mongoDB collection contains the following data
db.stack.find()
{ "_id" : "8GieRu" }
The _id is not single String of 12 bytes,
As per the MongoDB document of [ObjectID][1], id (string) – Can be a 24 byte hex string, 12 byte binary string or a Number.
Using Mongoose this collection is accessed using this Json
{"_id" : new mongoose.Types.ObjectId("8GieRu")}
and throws the below error
/node_modules/mongoose/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js:35
throw new Error("Argument passed in must be a single String of 12 bytes or
^
Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
at new ObjectID (/node_modules/mongoose/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js:35:11)
[1]: http://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html
Mongoose is strictly checking the ObjectId of fixed length, how can i pass Object_id using mongoose with the given length

You mix two concepts here.
While "_id" can have any value (even subdocument like {firstName:'Foo',lastName:'Simpson'}, "ObjectId" has a fixed set of types with some restrictions, as the error message correctly states.
So your statement should be
{'_id':'putWhatEverYouWantHere'}

I had the problem in my router order:
app.get('/jobs', controllers.jobs.getAllJobs);
app.get('/jobs/karriere', controllers.jobs.getAllJobsXML);
app.get('/jobs/:id', controllers.jobs.getJob);
app.get('/jobs/:id/xml', controllers.jobs.getJobXML);
I defined /jobs/karriere after /jobs/:id so the application thought that "karriere" was an ObjectID and returned the error. The code above is the working one.

Make sure the method you are using in client and server side match. This error also shows when you have e.g. GET being sent from client side and POST required on the server side.

You are passing any
ObjectID undefinded
If the ObjectID is undfined thaen this error will come.

In my case, I'm using mongoose. and I am not able to query with something like this:
{ "_id" : "8GieRu" }
Until I bumped into my model file and specified this line counter.model.js
var CounterSchema = new Schema({
_id: String,
sequence_value: Number
})
Notice that I specified the data type as string for _id in my model.
and the, in my query, I didn't need to convert string to ObjectId.
Query now works as simple as what the filter:
{ "_id" : "8GieRu" }

same problem faced by me but after a RND . I identified that i passed wrong {Id:Undefined} so problem occured so please firstly check your Id which you passed in URL.
Error = "http://localhost:4000/api/deleteBook/Undefined"
Right = "http://localhost:4000/api/deleteBook/5bb9e79df82c0151fc0cd5c8"

Related

Cast to ObjectId failed for value "some_id" at path "_id" for model "Category"

when I use findOne from mongoose version 5.9.12, I got some error like this :
error
https://i.stack.imgur.com/8kAcY.png
my code:
[code][2]
https://i.stack.imgur.com/v8Prd.png
my models:
models
From the mongoose documentation:
If you want to query by a document's _id, use findById() instead of
findOne().
The id is cast based on the Schema before sending the command.
So the recommended way to do this is:
Category.findById(categoryId)
If you really want to use findOne and specify _id inside the filter, you can convert the string using
Category.findOne( { _id: mongoose.Types.ObjectId(categoryId) })
to an ObjectId.
Edit: The actual problem is that your categoryId contains a trailing whitespace which causes this problem: "5f05445a9789663d08fb12d2 " - it should be "5f05445a9789663d08fb12d2".

Cast to ObjectId failed for value (reference to files)

As the title says.
For more context : I have a small script (launched by php via exec) that will search for a chapter with a given id to do some changes on the images (scramble them) that I didn't manage to do in php (I'm newbie working with files).
here are my schema
//instantiate mongoose-gridfs
var gridfs = require('mongoose-gridfs')({
collection:'files',
mongooseConnection: mongoose.connection
});
//Files = gridfs.model;
var FilesSchema = gridfs.schema;
FilesSchema.add({
_id: Schema.Types.ObjectId,
name: String,
mime: String,
filename: String,
type: String
});
Files = mongoose.model('Files', FilesSchema);
var pageSchema = Schema({
order: Number,
image: { type: Schema.Types.ObjectId, ref: 'Files' },
scrambled: Boolean
});
var ChapterSchema = Schema({
_id: Schema.Types.ObjectId,
pages: [pageSchema]
});
var Chapter = mongoose.model('Chapter', ChapterSchema, "Chapter");
When I do that
Chapter.findById(chapterId)
.populate('pages.image')
exec(...
It raises the CastError : { CastError: Cast to ObjectId failed for value "DBRef ...
The error object is long, so I don't paste it here
but here is a pastebin with the full error message/object
https://pastebin.com/8n54Dhzt
If I chan,ge the type of Image to Array I can access the properties I need after, but in that case I can't reset the images properly (it writes an array on db instead of a Ref)
My ref is in an embeddedDocument, like that
Chapter.pages[0].image
image is the property that have the ref.
I don't really understand why I have this error, I followed the docs for the refs/populate : http://mongoosejs.com/docs/populate.html
PS : A detail that can be important, The Reference is saved by DoctrineODM.
I use my node script to modify/encrypt the image, and then revert the encryption in js on my app.
PS2: sorry if a similar question is already posted and answered, there is so much post with the same error 'Cast to ObjectId failed for value' I admit I didn't read all of them, but those I read didn't help me.
EDIT : Update my code to use mongoose-gridfs Model instead of a different one + use subDocument instead of Array of object
Well that seems an error with chapterIdvalue. When you use collection.findById, the passed value must pass the ObjectId criteria which is
12-byte structure, the first 4 bytes of the ObjectId represent the
time in seconds since the UNIX epoch.
The next 3 bytes of the ObjectId represent the machine identifier.
The next 2 bytes of the ObjectId represent the process ID.
And the last 3 bytes of the ObjectId represent a random counter
value.
And if your passed id is not constructable to the pattern mentioned above this is definitely gonna throw the errors like you're getting.
So make sure you chapterId is correct or it is the same what you are getting from the database

failed: id is not defined while parsing unsing mongoose

So I am trying to parse some data using mongoose my schema looks like
data: [{
'order-id': String,
'sku': String,
'purchase-date': String,
'payments-date': String,
and I am trying to get the data using :
let parseddata = new ParsedDataModel(doc) ;
parseddata.data[0].order-id // failed id is not defined
While
parseddata.data[0].sku // is working
Is this a problem with the dash 6 ? How can I solve it ?
The problem is with your "dash".
Node js thinks it is a "minus" and your id is another variable.
Try using the following:
parseddata.data[0]["order-id"]
PS: I would recommend using ObjectId as the type for order-id instead of String. You can then populate the order document directly from this itself.

Update by Id not finding document

I am attempting to perform a relatively simple update using Mongoose:
var location = locationService.getLocation(typedLat, typedLong, travelRadius);
DocumentModel.update({_id : passedInId }, { location : location }, function(err, resp){
next(err, resp);
});
In this case passedInId is the string:
"561ee6bbe4b0f25b4aead5c8"
And in the object (test data I created) the id is:
"_id": ObjectId("561ee6bbe4b0f25b4aead5c8")
When I run the above however, matched documents is 0. I assume this is because passedInId is being treated like a string, however when I type it to an ObjectId:
var queryId = ObjectId(passedInId)
The result is the same, the document doesn't match. What am I missing? This seems like it should be obvious....
Mongoose will correctly interpret a string as an ObjectId. One of the following must be the case:
That record is not in the collection. Run a query in the mongo shell to check.
Mongoose I'd looking in collection other than the one containing your test data. Remember, by default, mongo will lowercase the name under which you register your model and will add an a "s" to it.
Lastly, and your answer speaks to this, maybe your model it's just not being updated with any new information.
This behavior was because I had not yet updated the model in mongoose to include the location element. There is no error, it just doesn't match or do anything.

MongoDB's BSON "_id" looks like scientific notation in Node.js

Occasionally I get a document with an _id value which javascript could and does interpret as scientific notation.
ONLY illustrate the problem I ran the following query.
db.users.find({$where:'this._id > 1'}).count()
2
There are hundreds of docs in this collection, but those 2 that evaluate as numbers cause problems when they get used in {$in:[]} clauses.
db.users.findOne({$where:'this._id > 1'})._id
ObjectId("5225141850742e0000002331") - see it's looks like scientific notation right?
I think I run into trouble when I want to store that _id as a string in another collection say as
friendsCollection:
{
_uid:"5225141850742e0000002331"
//more properties here
}
When I retrieve that value, Node (or Mongoose) interprets it as a number like "Infinity". Then my code ends up trying to search for the user with {_id:{$in:[Infinity]}} which throws an error.
I'm guessing there's a more robust way to store _id values or to handle properties you know to be _ids, but I don't know how.
Converting from hex string to binary representation of ObjectID
If you want to convert from a 24-byte hex string representation of an _id value into a binary ObjectID as stored in MongoDB, you can use ObjectID.createFromHexString:
// Need to require ObjectID class if not already included
ObjectID = require('mongodb').ObjectID;
var uid = ObjectID.createFromHexString("5205c4bd7c21105d0d99648c")
Comparing ObjectIDs
You should be using the $gt operator for ObjectID comparison rather than $where. The $where operator evaluates a JavaScript string and cannot take advantage of indexes; it will be much less performant (particularly for this use case).
So the findOne() example to find an _id greater than a given ObjectID should instead be:
db.users.findOne(
{ _id: { $gt: ObjectID("5205c4bd7c21105d0d99648c") } }
)._id
For a predictable outcome on finding the next higher ObjectID you should specify an explicit sort order using find() with sort and limit:
// Find next _id greater than ObjectID("5205c4bd7c21105d0d99648c")
db.users.find(
{_id: { $gt: ObjectID("5205c4bd7c21105d0d99648c") } }
).sort({_id:1}).limit(1).toArray()[0]._id
You'll notice that these find examples doesn't explicitly call createFromHexString. The default ObjectID() constructor will try to create an appropriate ObjectID based on whether the given value is a 24 byte hex string, 12 byte binary string, or a Number. If you know what sort of value you are providing, it is better to call the expected constructor to limit unexpected conversions (for example if you accidentally provided a Number instead of a hex string).
Database References (DBRefs)
MongoDB explicitly does not support joins, however there is a convention for storing database references (DBRefs) when you want to store the _id of a related document as a reference in another document. Mongoose has a ref option that simplifies working with references; see 'Population' in the Mongoose docs.
At some point I had problems when querying _id using the native driver. I fixed it by using ObjectId in my queries. You might find this helpful:
var ObjectId = require("mongodb").ObjectID;
query._id = { $gt: ObjectId(idString) }
Ahhh, maybe I should use the Mongoose data type "ObjectId" in my schemas.
For example I was using mongoose schemas like this:
locations:{
_uid:{type:String},//<--probably not good
lat:{type:Number},
lng:{type:Number}
},
Started using the Schema type "ObjectId":
locations:{
_uid:Schema.Types.ObjectId,//<--better?
lat: {type:Number},
lng: {type:Number}
},
I have to rebuild a lot of data to support this change. Also, I won't be sure until another one of those scientific notation _ids pop up, (I deleted the offending docs). However, this seams promising.

Resources