Bonjour j'essaye de rejoindre deux collections ...

#COLLECTION 1

const valuesSchema= new Schema({
    value: { type: String },
})

const categoriesSchema = new Schema({
    name: { type: String },
    values: [valuesSchema]
    })

mongoose.model('categories', categoriesSchema )

#COLLECTION 2

const productsSchema = new Schema({
    name: { type: String },
    description: { type: String },
    categories: [{
       type: mongoose.Schema.Types.ObjectId,
       ref: 'categories',
        }]
    })

mongoose.model('productos', productsSchema )

Maintenant, ce que je prétends faire est de rejoindre ces collections et d'avoir une sortie comme celle-ci.

#Exemple de document produit

{
    name: 'My laptop',
    description: 'Very ugly laptop',
    categories: ['5f55949054f3f31db0491b5c','5f55949054f3f31db0491b5b'] // these are _id of valuesSchema
}

#Production attendue

{
    name: 'My laptop',
    description: 'Very ugly laptop',
    categories: [{value: 'Laptop'}, {value: 'PC'}]
}

C'est ce que j'ai essayé.

                 {
                        $lookup: {
                            from: "categories",
                            let: { "categories": "$categories" },
                            as: "categories",
                            pipeline: [
                             {
                                $match: {
                                    $expr: {
                                        $in: [ '$values._id','$$categories']
                                    },
                                }
                             },
                            ]
                        }
                    }

Mais cette requête ne correspond pas ... Une aide s'il vous plaît?

1
Sergio Cano 17 sept. 2020 à 18:23

2 réponses

Meilleure réponse

Puisque vous essayez d'utiliser les requêtes non liées, je l'apprécie, vous pouvez facilement réaliser avec $unwind pour aplatir le tableau, puis $match. Pour regrouper le tableau, nous utilisons $group. Le $reduce permet de se déplacer sur chaque tableau et de stocker certaines valeurs particulières.

 [
  {
    $lookup: {
      from: "categories",
      let: {
        "categories": "$categories"
      },
      as: "categories",
      pipeline: [
        {
          $unwind: "$values"
        },
        {
          $match: {
            $expr: {
              $in: [
                "$values._id",
                "$$categories"
              ]
            },
            
          }
        },
        {
          $group: {
            _id: "$_id",
            values: {
              $addToSet: "$values"
            }
          }
        }
      ]
    }
  },
  {
    $project: {
      categories: {
        $reduce: {
          input: "$categories",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$this.values",
              "$$value"
            ]
          }
        }
      }
    }
  }
]

Fonctionnement du modèle Mongo

2
varman 17 sept. 2020 à 15:43

Tu peux essayer,

  • $lookup avec des catégories
  • $unwind déconstruire le tableau values
  • $match identifiant de catégories avec identifiant de valeur
  • $project pour afficher le champ obligatoire
db.products.aggregate([
  {
    $lookup: {
      from: "categories",
      let: { cat: "$categories" },
      as: "categories",
      pipeline: [
        { $unwind: "$values" },
        { $match: { $expr: { $in: ["$values._id", "$$cat"] } } },
        {
          $project: {
            _id: 0,
            value: "$values.value"
          }
        }
      ]
    }
  }
])

Terrain de jeux

3
turivishal 17 sept. 2020 à 16:14