2014-11-08 5 views
14

Ich habe das folgende Problem beim Abrufen von Daten aus MongoDB mit Mungo.Wie bekomme ich alle Werte, die einen Teil einer Zeichenkette mit Mungo-Suche enthalten?

Hier ist mein Schema:

const BookSchema = new Schema(
 
\t { 
 
\t \t _id:Number, 
 
\t \t title:String, 
 
\t \t authors:[String], 
 
\t \t subjects:[String] \t 
 
\t } 
 
);

wie Sie ich habe 2 Arrays eingebettet in das Objekt sehen, sagen wir mal der Inhalt der Autoren so etwas wie das sein kann: Autoren: ["Alex Ferguson", "Didier Drogba", "Cristiano Ronaldo", "Alex"]
was ich erreichen möchte, ist alle Alex in der Anordnung zu bekommen.

Bisher konnte ich die Werte erhalten, wenn sie den Wert vollständig entsprechen. Wenn ich versuche, diejenigen mit Alex zu bekommen, lautet die Antwort immer [].

Was ich wissen möchte ist, wie kann ich dies tun mit find() ohne Durchführung einer Map-reduzieren, um eine Ansicht oder eine Sammlung zu erstellen und dann find() darüber anwenden.

Der Code funktioniert hier genau für Spiele

Book.find({authors:req.query.q} , function(errs, books){ 
 
\t \t \t if(errs){ 
 
\t \t \t \t res.send(errs); \t 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t res.json(books); 
 
\t \t });

ich einige Dinge ausprobiert, aber kein Glück {Autoren: {$ elemMatch: req.query.q}} { Autoren: {$ in: [req.query.q]}}

Dieser gibt mir einen Fehler und obendrein ist in einem anderen Post, den ich hier gefunden habe, sehr ineffizient. {$ where: this.authors.indexOf (req.query.q) = -1}

und ich habe auch versucht, {Autoren: {$ regex: "./ Wert/i"}}

Die Map-Reduce funktioniert gut, ich muss es mit der anderen Methode arbeiten, um zu sehen, welche besser ist?

Jede Hilfe wird sehr geschätzt. Ich bin mir sicher, dass das einfach ist, aber ich bin neu mit NodeJS und Mongo und ich konnte es nicht alleine herausfinden.

Antwort

48

Sie haben das fast selbst in Ihren Tags beantwortet. MongoDB hat einen $regex-Operator, mit dem ein regulärer Ausdruck als Abfrage übergeben werden kann. So können Sie abfragen, für Zeichenfolgen mit „Alex“ Sie tun dies:

Books.find(
    { "authors": { "$regex": "Alex", "$options": "i" } }, 
    function(err,docs) { 
    } 
); 

Sie können dies auch tun:

Books.find(
    { "authors": /Alex/i }, 
    function(err,docs) { 

    } 
); 

Beide sind gültig und unterschiedlich, wie Sie in der richtigen unterstützte Syntax versucht, wie in die Dokumentation.

Aber natürlich, wenn Sie tatsächlich fragen "wie bekomme ich die 'Array' Ergebnisse nur für diejenigen, die 'Alex' irgendwo in der Zeichenfolge übereinstimmen?" dann ist das ein bisschen anders.

Complex Anpassung für mehr als einen Array-Element ist die Domäne der aggregation framework (oder möglicherweise verkleinern, aber das ist viel langsamer), wo man der Array-Inhalt „Filter“ benötigen.

Sie beginnen von sehr ähnlich. Der Schlüssel hier ist $unwind, um den Array-Inhalt zu "de-normalisieren", um in der Lage zu sein, als einzelne Dokumente richtig zu "filtern". Dann konstruiere das Array mit den "passenden" Dokumenten neu.

Books.aggregate(
    [ 
     // Match first to reduce documents to those where the array contains the match 
     { "$match": { 
      "authors": { "$regex": "Alex", "$options": i } 
     }}, 

     // Unwind to "de-normalize" the document per array element 
     { "$unwind": "$authors" }, 

     // Now filter those document for the elements that match 
     { "$match": { 
      "authors": { "$regex": "Alex", "$options": i } 
     }}, 

     // Group back as an array with only the matching elements 
     { "$group": { 
      "_id": "$_id", 
      "title": { "$first": "$title" }, 
      "authors": { "$push": "$authors" }, 
      "subjects": { "$first": "$subjects" } 
     }} 
    ], 
    function(err,results) { 

    } 
) 
+0

danke Neil, du hattest Recht. Mit einem der beiden Code-Codes, die Sie am Anfang gepostet haben, funktionierte es. – Dyan