Mungo: CastError: Die Umwandlung in ObjectId ist für den Wert "[Objekt Objekt]" im Pfad "_id" fehlgeschlagen.

74

Ich bin neu bei node.js, daher habe ich das Gefühl, dass dies etwas Dummes sein wird, das ich übersehen habe, aber ich konnte keine Antwort finden, die mein Problem behebt. Ich versuche, einen Pfad zu erstellen, der ein neues untergeordnetes Objekt erstellt, es dem Array der untergeordneten Objekte des übergeordneten Objekts hinzufügt und das untergeordnete Objekt an den Anforderer zurückgibt. Das Problem, auf das ich stoße, ist, dass der Knoten abstürzt, wenn ich die Zeichenfolgen-ID an findById übergebe

TypeError: Object {} hat keine Methode 'cast'

Wenn ich stattdessen versuche, eine ObjectId zu übergeben, erhalte ich

CastError: Die Umwandlung in ObjectId ist für den Wert "[Objektobjekt]" im Pfad "_id" fehlgeschlagen.

Hier ist eine grobe Darstellung meines Codes:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId; //Have also tried Schema.Types.ObjectId, mongoose.ObjectId

mongoose.connect('mongodb://user:password@server:port/database');

app.get('/myClass/:Id/childClass/create', function(request, result) {
  var id = new ObjectId(request.params.Id);
  MyClass.findById(id).exec( function(err, myClass) {
    if (err || !myClass) { result.send("error: " + err + "<br>" + JSON.stringify(id) || ("object '" + request.params.Id + "' not found: " + id)); return; }
    var child = ChildClass();
    myClass.Children.addToSet(child);
    myClass.save();
    result.send(child);
  });
});

Wenn ich diesen Code mit dem Pfad "/ myClass / 51c35e5ced18cb901d000001 / childClass / create" ausführe, ist dies die Ausgabe des Codes:

Fehler: CastError: Die Umwandlung in ObjectId für den Wert "[Objekt Objekt]" im Pfad "_id" {"Pfad": "51c35e5ced18cb901d000001", "Instanz": "Objekt-ID", "Validatoren": [], "Setter": [ ], "getters": [], "_ index": null}

Ich habe versucht, findOne zu verwenden und stattdessen {_id: id} zu übergeben, aber dies scheint genau das zu sein, was findById tut. Ich habe die verschiedenen Klassen für ObjectId ausprobiert, die auf anderen Websites aufgeführt sind. Ich habe versucht, ObjectId () wie eine Funktion anstelle eines Konstruktors aufzurufen, und das gibt undefiniert zurück. An diesem Punkt gehen mir die Ideen aus und es scheint nicht, dass es hilfreich ist, nach einer Antwort zu googeln. Irgendwelche Ideen, was ich falsch mache?

Wie gesagt, ich bin neu in Node / Mongo / Mongoose / Express. Wenn es also einen besseren Weg gibt, mein Ziel zu erreichen, lassen Sie es mich bitte wissen. Ich freue mich über jedes Feedback.

BEARBEITEN:

Nach der Problemumgehung von Peter Lyons habe ich einen weiteren Fehler gegoogelt, auf den ich gestoßen bin, und findByIdAndUpdate gefunden, das wie erwartet funktioniert und genau das tut, was ich mir erhofft hatte. Ich bin mir immer noch nicht sicher, warum findById und findOne mir solche Probleme bereiteten, und ich bin gespannt (möglicherweise muss ein Fehlerbericht eingereicht werden), daher lasse ich dies offen, falls jemand anderes eine Antwort hat.

jmblackmer
quelle
Ich vermute, Sie haben findOnemit einem einzigen aufgerufen ObjectId, findOneerwarten jedoch ein reguläres JS-Objekt mit Schlüssel- / Wertbedingungen.
Peter Lyons
Ich habe diese Frage hier beantwortet .
Bis
1
Überprüfen Sie Ihre Routen. Es kann sein, dass zwei Routen dasselbe Startbeispiel haben: "#GET / user /: userID und #GET / user / list". Die Route verwendet "Liste" als Eingabe für die Datenbank und gibt einen Fehler aus.
Jose Hernandez

Antworten:

72

Kurze Antwort: Verwenden Sie mongoose.Types.ObjectId .

Mungo (aber nicht Mongo) kann Objekt-IDs als Zeichenfolgen akzeptieren und sie für Sie richtig "umwandeln". Verwenden Sie also einfach:

MyClass.findById(req.params.id)

Die Einschränkung ist jedoch, dass, wenn req.params.ides sich nicht um ein gültiges Format für eine Mongo-ID-Zeichenfolge handelt, eine Ausnahme ausgelöst wird, die Sie abfangen müssen.

Das wichtigste verwirrende Problem ist, dass mongoose.SchemaTypeses Dinge enthält, die Sie nur beim Definieren von Mungo-Schemas verwenden, und mongoose.TypesDinge, die Sie beim Erstellen von Datenobjekten verwenden, die Sie in der Datenbank speichern oder Objekte abfragen möchten. Funktioniert also mongoose.Types.ObjectId("51bb793aca2ab77a3200000d"), gibt Ihnen ein Objekt, das Sie in der Datenbank speichern oder in Abfragen verwenden können, und löst eine Ausnahme aus, wenn eine ungültige ID-Zeichenfolge angegeben wird.

findOneNimmt ein Abfrageobjekt und übergibt eine einzelne Modellinstanz an den Rückruf. Und findByIdist buchstäblich ein Wrapper von findOne({_id: id})( siehe Quellcode hier ). Geradefind ein Abfrageobjekt und übergibt ein Array übereinstimmender Modellinstanzen an den Rückruf.

Geh einfach langsam. Es ist verwirrend, aber ich kann Ihnen garantieren, dass Sie verwirrt sind und zu diesem Zeitpunkt keine Fehler im Mungo treffen. Es ist eine ziemlich ausgereifte Bibliothek, aber es dauert einige Zeit, bis man den Dreh raus hat.

Die andere verdächtige Sache, die ich in Ihrem Snippet sehe, wird newbeim Instanziieren nicht verwendet ChildClass. Darüber hinaus müssen Sie Ihren Schemacode veröffentlichen, damit wir Sie bei der Suche nach verbleibenden CastErrors unterstützen können.

Peter Lyons
quelle
Wenn ich versuche, "mongoose.Types.ObjectId (" 51c35e5ced18cb901d000001 ") zu verwenden;" (indem ich es direkt in Code platziere), erhalte ich immer noch den Fehler "TypeError: Object {} hat keine Methode 'cast'". Ich habe auch versucht, es als Objekt zu instanziieren und habe den gleichen Fehler erhalten.
jmblackmer
Upgrade auf den neuesten Mungo? Ich bin am 3.6.11.
Peter Lyons
Das Aufrufen von MyClass.find (req.params.id) funktioniert. Sollten findOne und findById nicht auf die gleiche Weise funktionieren? Es scheint nur ein bisschen kontraintuitiv zu sein, die Funktion find zu haben, die ein einzelnes Dokument zurückgibt, wenn die anderen beiden vorhanden sind. Ich habe den Code geändert, um das erste Element des Arrays jetzt zu erhalten, aber es schlägt bei addToSet () jetzt mit "TypeError: Object {} hat keine Methode 'cast'" fehl.
jmblackmer
Ich bin auch am 3.6.11. Ich habe das alles neulich Nacht eingerichtet, also würde ich erwarten, dass alles bereits auf dem neuesten Stand ist.
jmblackmer
1
Sie verwenden die falsche Konstruktorfunktion. Verwenden Sie mongoose.Types.ObjectId. mongoose.Schema.ObjectIddient nur zum Definieren von Schemas.
Peter Lyons
44

Ich habe diesen Fehler festgestellt. Dies lag daran, dass der Wert, den Sie im Feld _id filtern möchten, kein ID-Format hat. Ein "Wenn" sollte Ihren Fehler beheben.

const mongoose = require('mongoose');

console.log(mongoose.Types.ObjectId.isValid('53cb6b9b4f4ddef1ad47f943'));
// true
console.log(mongoose.Types.ObjectId.isValid('whatever'));
// false

Überprüfen Sie zur Lösung immer, ob der Kriterienwert für die Suche eine gültige ObjectId ist

const criteria = {};
criteria.$or = [];

if(params.q) {
  if(mongoose.Types.ObjectId.isValid(params.id)) {
    criteria.$or.push({ _id: params.q })
  }
  criteria.$or.push({ name: { $regex: params.q, $options: 'i' }})
  criteria.$or.push({ email: { $regex: params.q, $options: 'i' }})
  criteria.$or.push({ password: { $regex: params.q, $options: 'i' }})
}

return UserModule.find(criteria).exec(() => {
  // do stuff
})
gsalgadotoledo
quelle
2
Richtig. Ich habe einen Endpunkt für den GETBenutzer mit a getestet. Es findByIdstellt sich heraus, dass der ID-Parameter 12 Bit betragen muss, da sonst der Mungo nicht gewirkt werden kann. Ich habe zufällige Kurzzahlen verwendet.
10110
3

Für all jene Leute, die an diesem Problem festhielten, es aber immer noch nicht lösen konnten: Ich stolperte über denselben Fehler und stellte fest, dass das _idFeld leer war.

Ich habe es hier ausführlicher beschrieben. Ich habe immer noch keine Lösung gefunden, außer die Felder in _idNicht-ID-Felder zu ändern, was für mich ein schmutziger Hack ist. Ich werde wahrscheinlich einen Fehlerbericht für Mungo einreichen. Jede Hilfe wäre dankbar!

Bearbeiten: Ich habe meinen Thread aktualisiert. Ich habe ein Ticket eingereicht und sie haben das fehlende _idProblem bestätigt . Es wird in der 4.xx-Version behoben, für die derzeit ein Release-Kandidat verfügbar ist. Der RC wird nicht für den produktiven Einsatz empfohlen!

Stefan Medack
quelle
Interessant, ich denke ich habe das gleiche Problem, meine _id war undefiniert und konnte daher nicht in ObjectId
Alexander Mills
3

Wenn Sie dieses Problem haben und irgendwo in dieser Richtung eine Auffüllung durchführen, lesen Sie dieses Mungo-Problem .

Update auf Mongoose 4.0 und das Problem wurde behoben.

ac360
quelle
2

Hatte das gleiche Problem, ich habe die ID einfach in einen String gezwungen.

Mein Schema:

const product = new mongooseClient.Schema({
    retailerID: { type: mongoose.SchemaTypes.ObjectId, required: true, index: true }
});

Und dann beim Einfügen:

retailerID: `${retailer._id}`
camstuart
quelle
1

Ich habe diesen Fehler erhalten. CastError: Die Umwandlung in ObjectId ist für den Wert "[Objektobjekt]" im Pfad "_id" fehlgeschlagen, nachdem ein Schema erstellt, dann geändert und nicht gefunden werden konnte. Ich habe alle Dokumente in der Sammlung gelöscht und konnte 1 Objekt hinzufügen, aber kein zweites. Am Ende habe ich die Sammlung in Mongo gelöscht und das hat funktioniert, als Mongoose die Sammlung neu erstellt hat.

Enkode
quelle
1

Für die Aufzeichnung: Ich hatte diesen Fehler beim Versuch, ein Unterdokument falsch zu füllen:

{
[CastError: Cast to ObjectId failed for value "[object Object]" at path "_id"]
message: 'Cast to ObjectId failed for value "[object Object]" at path "_id"',
name: 'CastError',
type: 'ObjectId',
path: '_id'
value:
  [ { timestamp: '2014-07-03T00:23:45-04:00',
  date_start: '2014-07-03T00:23:45-04:00',
  date_end: '2014-07-03T00:23:45-04:00',
  operation: 'Deactivation' } ],
}

look ^ value ist ein Array, das ein Objekt enthält: falsch!

Erläuterung: Ich habe Daten von PHP auf folgende Weise an eine node.js-API gesendet:

$history = json_encode(
array(
  array(
  'timestamp'  => date('c', time()),
  'date_start' => date('c', time()),
  'date_end'   => date('c', time()),
  'operation'  => 'Deactivation'
)));

Wie Sie sehen können, ist $ history ein Array, das ein Array enthält. Aus diesem Grund versuchen Mungos, _id (oder ein anderes Feld) mit einem Array anstelle einer Scheme.ObjectId (oder eines anderen Datentyps) zu füllen. Folgendes funktioniert:

$history = json_encode(
array(
  'timestamp'  => date('c', time()),
  'date_start' => date('c', time()),
  'date_end'   => date('c', time()),
  'operation'  => 'Deactivation'
));
Igor Parra
quelle
1

Ich habe auch diesen Mungofehler festgestellt. CastError: Die Umwandlung in ObjectId ist für den Wert "583fe2c488cf652d4c6b45d1" im Pfad "_ id" für den Modellbenutzer fehlgeschlagen

Also führe ich den Befehl npm list aus, um die Mongodb- und Mungo-Version in meinem lokalen zu überprüfen. Hier ist der Bericht: ......
......
├── [email protected]
├── [email protected]
.....

Es scheint, dass es ein Problem mit dieser Mongodb-Version gibt. Ich habe also deinstalliert und versucht, eine andere Version wie 2.2.16 zu verwenden

$ npm uninstall mongodbwird der mongodb aus dem Verzeichnis node_modules gelöscht. Danach installieren Sie die untere Version von Mongodb.
$ npm install [email protected]
Schließlich starte ich die App neu und der CastError ist weg !!

Arman Ortega
quelle
1

Ich hatte das gleiche Problem. Es stellte sich heraus, dass meine Node.js veraltet war. Nach dem Upgrade funktioniert es.

Rajesh Barik
quelle
1

Meine Lösung ist, dass ich Daten aus allen Dokumenten möchte und nicht _id, also

User.find({}, {_id:0, keyToShow:1, keyToNotShow:0})
jazeb007
quelle
0

Ändern Sie einfach den Pfad, der zum Beispiel funktionieren wird

app.get('/myClass/:Id/childClass/create', function(request, result) .....

ändern

app.get('/myClass**es**/:Id/childClass/create', function(request, result) .....

Ich habe gerade --es-- zum Pfad (myClass) hinzugefügt, um (myClasses) zu werden.

Jetzt sollte funktionieren und wird diesen Fehler nicht sehen

happyCoder
quelle
0

Ich hatte das gleiche Problem, nachdem ich mein Schema aktualisiert hatte. Ich habe vergessen, dass ich das Modell mit der alten ID aufgerufen habe, die von mir erstellt wurde. Ich habe mein Schema von so etwas wie aktualisiert:

patientid: {
           type: String,
            required: true,
            unique: true
          }, 

zu

patientid: { type: mongoose.SchemaTypes.ObjectId, ref: "Patient" },

Es stellte sich heraus, da mein Code groß ist, habe ich das findOnemit der alten ID angerufen , daher das Problem.

Ich poste hier nur, um jemand anderem zu helfen: Bitte überprüfen Sie Ihren Code auf unbekannte falsche Anrufe ! es kann das Problem sein, und es kann Ihre riesigen Kopfbedeckungen retten!

Jorge Pires
quelle
0

Ich bin nicht sicher, ob dies helfen wird, aber ich habe das Problem behoben, indem ich Mungo wie unten importiert und wie unten implementiert habe

const mongoose = require('mongoose')

_id: new mongoose.Types.ObjectId(),
Kingsley Akpan
quelle