2017-09-28 1 views
0

Ich habe eine Sammlung von 200k Dokumente, die jeweils ein "CustomerName" -Feld enthält. Es gibt ungefähr 1k eindeutige "customerName" -Werte. (das Feld ist indiziert)Mungo - render verschiedene Werte und slugify diese Werte

Ich muss eine Liste dieser Kundennamen rendern und generieren Sie einen Slug für jeden, so dass ich in meinem Routing-URL verwenden kann.

Der nächste Schritt wäre, eine Seite für jeden customerName zu rendern, die alle Dokumente anzeigt, die diesen customerName enthalten. Hier

ist, was ich habe so weit,

/// Customer.js

const rmaSchema = new Schema({ 
    CustomerName: { type: String, index: true }, 
    slug: String }, 
    { collection : 'mycompany' // collection name 
    }); 

rmaSchema.pre('save', function(next) { 
    this.slug = slugify(this.CustomerName) ; 
    next(); 
}); 

const rmaModel = mongoose.model('Rma', rmaSchema); 

module.exports = rmaModel; 

// function to slugify a name 
function slugify(text) { 
    return text.toString().toLowerCase() 
    .replace(/\s+/g, '-')   // Replace spaces with - 
    .replace(/[^\w\-]+/g, '')  // Remove all non-word chars 
    .replace(/\-\-+/g, '-')   // Replace multiple - with single - 
    .replace(/^-+/, '')    // Trim - from start of text 
    .replace(/-+$/, '');   // Trim - from end of text 
} 

/// Customer.Controller.js

function showCustomers(req, res){ 

Rma.distinct('CustomerName', function(err, customers) { 
    if (err){ 
     res.status(404); 
     res.send('customers not found!'); 
    } 

    res.render('pages/customers', {customers: customers}); 

    }); 
}; 

module.exports = showCustomers; 

/// customer.ejs

<table class="table table-bordered table-hover table-striped"> 
    <tbody> 
    <% for (var customer of customers) { %> 
     <tr> 
     <td><%= customer.CustomerName %></td>  
     <td><a href="/events/<%= customer.slug %>" class="btn btn-sm btn-primary">Generate Report</a></td> 
     </tr> 
    <% } %> 
</tbody> 
+0

Sind Schnecken nicht einzigartig? – Mikey

Antwort

0

Ich verstehe nicht ganz Ihre Controller-Logik gibt, aber nur, damit wir etwas Konkretes darüber zu sprechen haben, ist hier, wie Sie die Schnecken in der Route verweisen konnte:

app.get('/rma/:slug', function(req, res, next) { 
    console.log(req.params.slug) 
    // mongo query to find slug 
    if (foundRecord) { 
     return res.render('pages/customer', { 
      customer: foundRecord 
     }) 
    } else { 
     return res.render('404', { slug: req.params.slug }) 
    } 
}) 

Ihre Slug Funktion gut sieht ziemlich.

Eine Sache, die ich erwähnen möchte, ist, dass Sie in Ihrem aktuellen Controller nicht explizite return verwenden, so ist es wichtig zu beachten, dass, wenn ein Benutzer diese Bedingung 404 trifft, Ihre API die Header dafür und kann weitermachen. Ich bin nicht 100% sicher, dass mit res.send, aber Sie können definitiv beide zu return res.send() und return res.render() ändern, um es ein wenig zu verhärten. Die Rückkehr wird sicherstellen, dass sie die Funktion in diesem Moment verlässt.

Wenn Sie Probleme mit dem Slugging und De-Slugging haben, empfehle ich Ihnen, den Slug zusammen mit dem Datensatz zu speichern und ihn auch zu aktualisieren, wenn der Benutzer seinen Namen aktualisiert.

{ 
    _id: 'g9sd76gft9s87dfgs8d7f' 
    CustomerName: 'Bob Alice', 
    CustomerNameSlug: 'Bob-Alice' 
} 

Wie in diesem Kommentar von Mikey oben erwähnt, werden Sie Namenskollisionen in Ihrer Route auftreten, wenn Sie keine eindeutigen Schnecken haben.

Um Abhilfe zu schaffen, wenn Sie den Slug mit jedem Datensatz in Mongo DB speichern, können Sie etwas anheften, das es einzigartig macht, aber ich würde dies nur tun, wenn Ihre Kunden nur auf der Route ankommen, indem Sie auf Ihre Benutzeroberfläche klicken und nicht manuell die URL eingeben. Sie könnten etwas wie slugify( $ {CustomerName} $ {timestamp} ) machen, was eine einigermaßen einzigartige Garantie bietet.

Hmm, ich habe einen Template-String verwendet, den der StackOverflow-Syntax-Highlighter wegen der doppelten Grabakzentverwendung nicht zu mögen scheint. Um es klar zu sagen, das wird das gleiche Ergebnis wie slugify(CustomerName + timestamp.toString()) ergeben. Es ist nur eine einfache Verkettung.

+1

Vielen Dank für Ihre Antwort! Am Ende des Tages bin ich mir nicht sicher, ob ich überhaupt die Schnecke brauche. Ich möchte nur alle eindeutigen Kundennamen anzeigen und dann alle mit diesem Namen verknüpften Dokumente rendern können, wenn auf den Kundennamen geklickt wird. Ich bin etwas verloren bei der Struktur dieses –

+0

Das Beispiel, das ich zeigte, könnte dafür sehr hilfreich sein. Spielen Sie mit einer Route, die 'routename /: etwas 'verwendet, weil': something' als 'req.params.something' verfügbar ist.Sie könnten die Ansicht laden und mit EJS einen Link auf 'Click Here' – agm1984

+0

Ich bin ziemlich sicher Mongo DB IDs sind URL sicher (Hinweis Hinweis) – agm1984