2017-10-17 19 views
0

J'ai un modèle Mongoose appelé Session avec un champ nommé cours (Cours modèle) et je veux effectuer une recherche en texte intégral sur sessions avec recherche en texte intégral, aussi je veux des résultats globaux en utilisant des champs de cours sur le terrain sous et de sélectionner certains domaines comme cours, Date, etc. J'ai essayé les éléments suivants:Mongoose agrégation sous champ avec recherche en texte intégral et projet

Session.aggregate(
     [ 
      { 
       $match: { $text: { $search: 'web' } } 
      }, 
      { $unwind: '$course' }, 
      { 
       $project: { 
        course: '$course', 
        date: '$date', 
        address: '$address', 
        available: '$available' 
       } 
      }, 
      { 
       $group: { 
        _id: { title: '$course.title', category: '$course.courseCategory', language: '$course.language' } 
       } 
      } 
     ], 
     function(err, result) { 
      if (err) { 
       console.error(err); 
      } else { 
       Session.deepPopulate(result, 'course course.trainer 
        course.courseCategory', function(err, sessions) { 
        res.json(sessions); 
      }); 
      } 
     } 
    ); 

Mes modèles:

  • session

    schema = new mongoose.Schema( { date: { type: Date, required: true }, course: { type: mongoose.Schema.Types.ObjectId, ref: 'course', required: true }, palnning: { type: [Schedule] }, attachments: { type: [Attachment] }, topics: { type: [Topic] }, trainer: { type: mongoose.Schema.Types.ObjectId, ref: 'trainer' }, trainingCompany: { type: mongoose.Schema.Types.ObjectId, ref: 'training-company' }, address: { type: Address }, quizzes: { type: [mongoose.Schema.Types.ObjectId], ref: 'quiz' }, path: { type: String }, limitPlaces: { type: Number }, status: { type: String }, available: { type: Boolean, default: true }, createdAt: { type: Date, default: new Date() }, updatedAt: { type: Date } }, { versionKey: false } );

  • Cours

let schema = new mongoose.Schema( { title: { type: String, required: true }, description: { type: String }, shortDescription: { type: String }, duration: { type: Duration }, slug: { type: String }, slugs: { type: [String] }, program: { content: { type: String }, file: { type: String } }, audience: [String], requirements: [String], language: { type: String, enum: languages }, price: { type: Number }, sections: [Section], attachments: { type: [Attachment] }, tags: [String], courseCategory: { type: mongoose.Schema.Types.ObjectId, ref: 'course-category', required: true }, trainer: { type: mongoose.Schema.Types.ObjectId, ref: 'trainer' }, trainingCompany: { type: mongoose.Schema.Types.ObjectId, ref: 'training-company' }, status: { type: String, default: 'draft', enum: courseStatus }, path: { type: String }, cover: { type: String, required: true }, duration: { type: Number, min: 1 }, createdAt: { type: Date, default: Date.now }, updatedAt: { type: Date } }, { versionKey: false } );

Je ne sais pas si ce que j'ai essayé est me apporter va ce que je veux et je reçois cette erreur concernant les $ opérateur se détendre:

MongoError: exception: Value at end of $unwind field path '$course' must be an Array, but is a OID

Toute aide sera vraiment apprécié.

+0

Il vous manque $ lookup requis pour extraire le document de cours en joignant l'ID de l'objet de cours du document de session à l'ID dans le document de cours. Insérez l'étape de recherche entre les étapes '$ match' et' $ unwind'. Quelque chose comme '{$ recherche: { de: "bien sûr", localField: "bien sûr", foreignField: "_id", comme: "bien sûr" }}' . Ajuster pour utiliser le nom de collection correct, le champ local et le champ étranger. – Veeram

+0

@Veeram J'ai eu cette erreur: 'MongoError: exception: Nom de l'étape de pipeline non reconnue: '$ lookup' – jemlifathi

+0

Ma version de mangouste est **^4.11.12 ** si elle a un sens. – jemlifathi

Répondre

1

Vous pouvez essayer l'agrégation ci-dessous.

Il vous manque $lookup requis pour extraire le document de cours en joignant l'ID de l'objet de cours du document de session à l'ID dans le document de cours.

$project pour conserver les champs désirés dans la sortie.

Session.aggregate([ 
    { 
    "$match": { 
     "$text": { 
     "$search": "web" 
     } 
    } 
    }, 
    { 
    "$lookup": { 
     "from": "courses", 
     "localField": "course", 
     "foreignField": "_id", 
     "as": "course" 
    } 
    }, 
    { 
    "$project": { 
     "course": 1, 
     "date": 1, 
     "address": 1, 
     "available": 1 
    } 
    } 
]) 

Course est un tableau avec un document de cours. Vous pouvez utiliser le $arrayElemAt pour projeter le document.

"course": {"$arrayElemAt":["$course", 0]} 
+0

Il fonctionne très bien excepté lors de l'ajout d'un ** match $ ** même avec une vraie condition comme par exemple: '{ \t \t \t \t $ match: { 'disponible': true} }' – jemlifathi

+0

Laissez-vous entendre, il est ne fonctionne pas lorsque vous ajoutez "disponible" pour correspondre à la scène? Quelque chose comme '{ "match $": { "$ text": { "recherche $": "web" }, "disponible": true} }' devrait fonctionner. – Veeram

+0

Non, même seulement '{" $ match ": {" available ": true}}' ne fonctionne pas – jemlifathi