与mongodb的一对多关系?

时间:2018-05-23 13:29:34

标签: mongodb express mongoose async.js

我有两个名为serviceaccount.keytabktutil addent -password -p serviceaccount@MYDOMAIN.COM -k 1 -e RC4-HMAC - it will ask you for password of serviceaccount - wkt serviceaccount.keytab q 的模式:

HotelSchema

因此有两个名为PricelineSchema// schemas.js const mongoose = require("mongoose") module.exports.HotelSchema = mongoose.Schema({ name: { type: String, required: true, unique: true, index: true }, accommodation_type: { type: String, enum: ["هتل", "هتل آپارتمان", "مهمانسرا"], index: true }, pricelines: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Priceline' }] }) module.exports.PricelineSchema = mongoose.Schema({ source: { type: String, required: true, index: true }, price: { type: String, required: true, index: true }, hotel: { type: mongoose.Schema.Types.ObjectId, ref: "Hotel" } }) 的模型:

Hotel

故事简短我有一个端点,其中Priceline使用了:

// models.js
const mongoose = require("mongoose")
const {HotelSchema, PricelineSchema} = require("./schemas")

module.exports.Priceline = mongoose.model("Priceline", PricelineSchema)
module.exports.Hotel = mongoose.model("Hotel", HotelSchema)

当我调用async.waterfall时,结果是一个空数组,我不知道为什么?!

const async = require("async")
const bodyParser = require("body-parser")
const app = express()
app.use(bodyParser.json())

const { Hotel, Priceline } = require("./models")

function buildPricelineMany (arr, hotel) {
  const pricelines = []
  for (let priceline of arr) {
    pricelines.push(
      new Priceline({
        source: priceline.source,
        price: priceline.price,
        hotel: hotel._id
      })
    )
  }
  return pricelines
}

app.put("/hotels", (req, res) => {
  async.waterfall(
    [
      function (callback) {
        Hotel.findOne({ name: req.body.name })
          .populate("pricelines")
          .exec(function (err, hotel) {
            if (err) return callback(hotel)
            return callback(null, hotel)
          })
      },
      function (hotel, callback) {
        const pricelines = buildPricelineMany(req.body.pricelines, hotel)
        Priceline.insertMany(pricelines)
          .then(docs => callback(null, hotel, docs))
          .catch(err => {
            return callback(err)
          })
      }
    ],
    function (error, hotel, pricelines) {
      if (error) {
        res.status(500).jsonp({ errors: [error] })
        return
      }

      res.status(200).jsonp(hotel)
    }
  )
})

app.listen(8080, "localhost")

我创建一对多关系的方式与文档the way to manually configure HTTPS完全相同。

这是我的收藏:

populate('pricelines')

2 个答案:

答案 0 :(得分:1)

现在填充的是历史...您应该使用$lookup填充_id pricelines字段中的hotel酒店

以下是(mongodb版本3.6)

的示例
db.collection.aggregate([
  { "$match": {  "name": req.body.name } },
  { "$lookup": {
    "from": Priceline.collection.name,
    "let": { "hotel_id": "$_id" },
    "pipeline": [
       { "$match": { "$expr": { "$eq": [ "$hotel", "$$hotel_id" ] } } }
     ],
     "as": "pricelines"
  }},
 ])

如果您有 mongodb版,则 3.6 ,那么您可以使用此

 db.collection.aggregate([
  { "$match": {  "name": req.body.name } },
  { "$lookup": {
    "from": Priceline.collection.name,
    "localField": "_id",
    "foreignField": "hotel",
    "as": "pricelines"
  }},
 ])

$lookup的最佳用途之一是,您不需要将_id数组放入集合(用于填充),这会减少集合大小

答案 1 :(得分:0)

收到对象后,您是否尝试过填充?像这样我的意思是:

...
.exec(function (err, hotel) {
   Priceline.populate(hotel, {path:'pricelines'}, function (err, populatedHotels){
        //do your things here
    })
});
...

我最近偶然发现了这一点,我认为这可能有所帮助。 让我知道