2016-08-07 9 views
1

Ich habe eine Sammlung Cats:Wie sortiere ich Sammlung nach Array von Werten in der Veröffentlichung? (Array nicht in der Sammlung Artikel)

{ 
    "_id" : "rRq76LxsnPfmuh9DD", 
    "register_id" : "20gnr3g", 
    "name" : "Meow", 
    "created_at": ..., 
    ... 
} 

Jedes Element in dieser Kollektion einzigartiger hat _id und einzigartige register_id. Ich habe auch RatingLog für die Katzen und jetzt möchte ich Katzen nach dieser Bewertung sortieren.

[ 
    "20gnr3g", 
    "3412r23", 
    "221n415", 
    "Q0g4rEg", 
    ... 
] 

Jetzt will ich das Array verwenden für die Sortierung der Cats Sammlung: Vom RatingLog können wir Reihe von Katze register_id s nach Bewertung bestellt bekommen. Beachten Sie, dass alle Einträge in Cats möglicherweise nicht bewertet wurden, aber alle Einträge sollten zurückgegeben werden: Zuerst in Bestellung und Ruhe Artikel von created_at Feld.

Meine Veröffentlichung Code atm:

Meteor.publish('allCats', function(sortType) { 
    if (sortType == 'rating') { 
     return Cats.find({}, {sort: { 
      // How to sort by registerIds array??? 
     }}); 
    } 

    return Cats.find({}, {sort: { created_at: 1 }}); 
}); 

Die Frage ist also: Wie in der Veröffentlichung Cats Sammlung von register_id s Array und created_at Feld sortieren?

Antwort

1

Wenn Sie es reaktiv machen wollen, können Sie die Bewertungen entweder mit den Katzen speichern oder sie später in Javascript abbilden. Eine dritte, nicht-reaktive Option wäre wahrscheinlich die Verwendung der MongoDB-Aggregationspipeline mit Joins (hinzugefügt in 3.2), aber ich bin nicht vertraut genug, um ein Beispiel zu diesem Zeitpunkt zu geben.

Wenn Sie die Bewertungen mit den Katzen zu speichern, wird es sehr einfach:

Meteor.publish('allCats', function (sortType) { 
    /** 
    * Assuming that Cats contains contents of the form: 
    * { 
    * "_id" : "rRq76LxsnPfmuh9DD", 
    * "register_id" : "20gnr3g", 
    * "name" : "Meow", 
    * "created_at": ..., 
    * "rating": 123, 
    * ... 
    * } 
    **/ 
    if (sortType == 'rating') { 
    return Cats.find({}, { sort: { rating: 1 } }); 
    } 

    return Cats.find({}, { sort: { created_at: 1 } }); 
}); 

Wenn Sie RatingLog getrennt zu halten und wollen die Ergebnisse reaktiv zu sein, müssen Sie Ihre Sortierung auf dem Client ausführen -Seite; sowohl allCats und allCatRatings veröffentlichen:

Meteor.publish('allCats', function() { 
    return Cats.find({}, {sort: { created_at: 1 }}); 
}); 

Meteor.publish('allCatRatings', function() { 
    return RatingLog.find(); 
}); 

sowohl von denen, nach der Anmeldung, die Ratings abrufen und die Art auszuführen:

Template.myTemplate.helpers({ 
    cats() { 
    const sortType = Template.instance().sortType; 
    if (sortType === 'rating') { 
     return getCatsByRating(); 
    } 
    return getCatsByCreationDate(); 
    } 
}); 

function getCatsByCreationDate() { 
    return Cats.find({}, {sort: { created_at: 1 }}); 
} 

function getCatsByRating() { 
    /** 
    * Assuming that RatingLog contains contents of the form { _id: catId, rating: 123 } 
    **/ 
    const ratings = {}; 
    RatingLog.find().forEach(entry=>ratings[entry._id] = entry.rating); 

    const defaultRating = 0; 
    return Cats.find().fetch().sort(function (catA, catB) { 
    const catARating = ratings[catA._id] || defaultRating; 
    const catBRating = ratings[catB._id] || defaultRating; 
    return catARating - catBRating; 
    }); 
} 
Verwandte Themen