2017-03-10 10 views
1

Ich habe folgendes Mungo Schema:Mongoose bevölkern und sortiert nach Länge Kampf

const userSchema = new mongoose.Schema({ 
    email: { type: String, unique: true }, 
    fragments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Fragment'}] 
}, { timestamps: true, collection: 'user' }); 

Und

const fragmentSchema = new mongoose.Schema({ 
    text: String, 
    owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
}, { timestamps: true, collection: 'fragment' }); 

In den Daten, ich habe eine Referenz in den Fragment, aber nicht in den User:

Benutzer:

{ 
    "_id" : ObjectId("58373e571cbccb010012bfcd"), 
    "email" : "[email protected]", 
    // no "fragments": [ObjectId('58075ce37b7f2f01002b718f')] etc. 
} 

Fragment:

{ 
    "_id" : ObjectId("58075ce37b7f2f01002b718f"), 
    "text" : "Donc, il faut changer de méthode", 
    "owner" : ObjectId("58075ce27b7f2f01002b717f") 
} 

Ich möchte Benutzer durch die Anzahl der Anzahl der Fragmente sortiert abfragen, und ich dies nicht erreichen können ...

Erstens würde Ich mag diese Arbeit machen :

User.find({_id: '58075ce27b7f2f01002b717f'}) 
    .populate('fragments').exec(console.log) 

kehrt

{ 
    _id: 58075ce27b7f2f01002b717f, 
    email: '[email protected]', 
    fragments: [] 
} 

während sollte ich bei mindestens die obigen fragment enthalten.

Und die sortierte Abfrage über, hier, wo ich jetzt bin:

User.aggregate([ 
    { "$project": { 
    "email": 1, 
    "fragments": 1, 
    "nbFragments": { "$size": { "$ifNull": [ "$fragments", [] ] } } 
    }}, 
    { "$sort": { "nbFragments": -1 } } 
], console.log) 

Wenigstens läuft es, aber alle nbFragments Felder auf 0 gesetzt Dies ist auf die Tatsache zusammenhängen könnte, dass .populate('fragments') nicht der Fall ist Arbeit, aber ich kann mir nicht sicher sein.

Danke für die Hilfe, ich habe nicht so viel Mühe erwarten MongoDB mit ...


EDIT: Dank @Veeram, leider ist Ihre Lösung nicht funktioniert:

User.find({}).find({_id: '58075ce27b7f2f01002b717f'}).populate('fragments').exec(console.log) 
[ { _id: 58075ce27b7f2f01002b717f, 
    email: '[email protected]', 
    // no fragments entry 
} ] 

, während ich aktualisiert mein Schema:

userSchema.virtual('fragments', { 
    ref: 'Fragment', 
    localField: '_id', 
    foreignField: 'owner', 
    options: { sort: { number: 1 }}, // Added sort just as an example 
}); 

Und in Bezug auf das Aggregat, mit:

User.aggregate([{ 
    $lookup: { 
    from: 'Fragment', 
    localField: '_id', 
    foreignField: 'owner', 
    as: 'fragments' 
    } 
}, { "$project": { 
    "email": 1, 
    "fragments": 1, 
    "nbFragments": { 
    "$size": { "$ifNull": [ "$fragments", [] ] } } 
}}, { "$sort": { "nbFragments": -1 } } 
]).exec(console.log) 

ich:

{ 
    _id: 58075ce27b7f2f01002b717f, 
    email: '[email protected]', 
    fragments: [] // fragments are always empty while they shouldn't! 
} 

Antwort

0

Getestet mit folgenden Daten

User: 

{ 
    "_id" : ObjectId("58373e571cbccb010012bfcd"), 
    "email" : "[email protected]" 
} 

Fragment: 

{ 
    "_id" : ObjectId("58075ce37b7f2f01002b718f"), 
    "text" : "Donc, il faut changer de méthode", 
    "owner" : ObjectId("58373e571cbccb010012bfcd") 
} 

Antwort

[{"_id":"58373e571cbccb010012bfcd","email":"[email protected]","fragments":[{"_id":"58075ce37b7f2f01002b718f","text":"Donc, il faut changer de méthode","owner":"58373e571cbccb010012bfcd"}],"nbFragments":1}] 

Sie Schema definieren owner zu verwenden, um die fragments auch virtuelle Population genannt zu füllen. http://mongoosejs.com/docs/populate.html

const userSchema = new mongoose.Schema({ 
     email: { type: String, unique: true } 
    }, { timestamps: true, collection: 'user' }); 

var User = mongoose.model("User", userSchema); 

const fragmentSchema = new mongoose.Schema({ 
    text: String, 
    owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
}, { timestamps: true, collection: 'fragment' }); 

var Fragment = mongoose.model("Fragment", fragmentSchema); 

userSchema.virtual('fragments', { 
    ref: 'Fragment', 
    localField: '_id', 
    foreignField: 'owner', 
    options: { sort: { text: -1 }}, // Added sort just as an example 
}); 

Dies wird nun wie erwartet, aber ich weiß nicht, einen Weg auf einigen dynamischen Bereich wie Anzahl der Anzahl der Fragmente in Mungo zu sortieren.Ich glaube nicht, es möglich ist,

User.find({_id: '58373e571cbccb010012bfcd'}) 
     .populate('fragments').exec(function (err, user) { 
      console.log(JSON.stringify(user)); 
     }); 

Okay, jetzt dynamische Sortierung, Sie alternative Roh Mongo Abfrage mit einem $lookup (äquivalent populate) zu verwenden.

const userSchema = new mongoose.Schema({ 
     email: { type: String, unique: true } 
    }, { timestamps: true, collection: 'user' }); 

var User = mongoose.model("User", userSchema); 

const fragmentSchema = new mongoose.Schema({ 
    text: String, 
    owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
}, { timestamps: true, collection: 'fragment' }); 

User.aggregate([{ 
    $lookup: { 
    from: 'fragment', 
    localField: '_id', 
    foreignField: 'owner', 
    as: 'fragments' 
    } 
}, { "$project": { 
    "email": 1, 
    "fragments": 1, 
    "nbFragments": { 
    "$size": { "$ifNull": [ "$fragments", [] ] } } 
}}, { "$sort": { "nbFragments": -1 } } 
]).exec(function (err, user) { 
     console.log(JSON.stringify(user)); 
}) 
+0

Dank @Veeram. Ich habe meine Frage mit den Zwischenergebnissen bearbeitet. Funktioniert immer noch nicht :(Ich überlege, die doppelte Referenz im Benutzerdokument hinzuzufügen, mit Push/Pull-Callbacks, würde es Sinn machen, nicht wahr? –

+0

Sie sind willkommen. Virtual Populate ist nur von Version 4.5 verfügbar Mungo. Getestet sowohl die Varianten mit 4.8.6 als auch mit dem neuesten Code aktualisiert.Für die Aggregatfunktion sollte der Sammlungsname im 'from' Feld in der' $ lookup' Fragment Kleinschreibung sein f. Das sollte funktionieren. – Veeram

+0

Ich benutze 4.6 Es sollte also funktionieren, aber da die Bestellung nicht möglich ist und das * erwartete Verhalten * scheint, dass die Schlüssel im Dokument gespeichert sind, werde ich nach dieser Lösung suchen und versuchen herauszufinden, wie es funktioniert! Mongodb ist hart aber –

Verwandte Themen