2014-11-08 20 views
14

Ho il seguente problema nel recuperare i dati da MongoDB usando mangusta.Come trovare tutti i valori che contengono una parte di una stringa utilizzando la ricerca di mangusta?

Ecco il mio schema:

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

come potete vedere ho 2 matrici incorporate nell'oggetto, diciamo il contenuto degli autori può essere qualcosa di simile: gli autori: ["Alex Ferguson", "Didier Drogba", "Cristiano Ronaldo", "Alex"]
quello che sto cercando di ottenere è ottenere tutto l'Alex nella matrice.

Finora, sono riuscito a ottenere i valori se corrispondono completamente al valore. Comunque se provo a ottenere quelli che contengono Alex la risposta è sempre [].

Quello che voglio sapere è come posso farlo usando find() senza eseguire una mappa-riduci per creare una vista o una collezione e quindi applicare find() su quello.

Il codice qui lavora per corrispondenze esatte

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 });

ho provato alcune cose, ma senza fortuna {autori: {$ elemMatch: req.query.q}} { autori: {$ in: [req.query.q]}}

Questo mi dà un errore e in più dice che è molto inefficiente in un altro post che ho trovato qui. {$ dove: this.authors.indexOf (req.query.q) = -1}

e ho anche provato {autori: {$ regex: "./ valore/i"}}

La mappa-riduzione funziona bene, ho bisogno di farlo funzionare utilizzando l'altro approccio per vedere quale è meglio?

Qualsiasi aiuto è molto apprezzato. Sono sicuro che sia facile, ma sono nuovo con NodeJS e Mongo e non sono stato in grado di capirlo da solo.

risposta

48

Hai quasi risposto a te stesso nei tuoi tag. MongoDB ha un operatore $regex che consente di inviare un'espressione regolare come una query. Quindi si esegue una query per le stringhe contenenti "Alex" si esegue questa operazione:

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

Si può anche fare questo:

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

    } 
); 

Entrambi sono validi e diverso da come si è tentato nella sintassi supportata corretta come mostrato nella la documentazione.

Ma ovviamente se si sta effettivamente chiedendo "come ottenere i risultati 'array' solo per quelli che corrispondono a 'Alex' da qualche parte nella stringa?" allora questo è un po 'diverso.

corrispondenza complesso per più di un elemento dell'array è il dominio del aggregation framework (o, eventualmente, MapReduce, ma che è molto più lento), in cui è necessario "filtrare" il contenuto dell'array.

Si inizia più o meno la stessa cosa. Il tasto qui è $unwind per "de-normalizzare" il contenuto dell'array in modo da poter essere "filtrato" correttamente come singoli documenti. Quindi ri-costruire la matrice con i documenti "corrispondenti".

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

grazie Neil, avevi ragione. Ha utilizzato uno qualsiasi dei due pezzi di codice che hai postato all'inizio. – Dyan

Problemi correlati