arrays - Mongoose - 填充二维数组

标签 arrays node.js mongoose nested populate

我正在尝试使用 NodeJS 中的 Mongoose 填充二维数组内的字段。

这就是我的翻译数据的结构:

{
  "_id" : ObjectId("5cc3fa08c2d98a3ac8e4889a"),
  "translation" : [
         [
                 {
                         "x" : "999",
                         "y" : "999",
                         "width" : "555",
                         "height" : "555",
                         "idVideo" : ObjectId("5cc401f319bac9285ce0a235")
                  },
                  {
                         "x" : "111",
                         "y" : "111",
                         "width" : "666",
                         "height" : "666",
                         "idVideo" : ObjectId("5cc401f319bac9285ce0a235")
                  }
         ]
   ],
  "__v" : 2
}

翻译架构.js

const TranslationSchema = mongoose.Schema(
  {
    idDocument: {
      type: Schema.Types.ObjectId,
      ref: 'Document'
    },
    translation: {
      type: [[TranslationCoordinateSchema]],
      default: []
    }
  },
  {
    strict: true
  }
);

翻译坐标架构.js

const TranslationCoordinateSchema = mongoose.Schema({
  x: {
    type: String
  },
  y: {
    type: String
  },
  width: {
    type: String
  },
  height: {
    type: String
  },
  idVideo: {
    type: Schema.Types.ObjectId,
    ref: 'TranslationVideo'
  },
  _id: false
});
<小时/>

我尝试了很多方法,但我不知道如何构建路径,因为它是一个二维数组。 例如我尝试过:

Translation.findById(idTranslation).populate({
        path: 'translation.idVideo',
        model: 'TranslationVideo'
    });

Translation.findById(idTranslation).populate({
        path: 'translation.translation.idVideo',
        model: 'TranslationVideo'
    });

也许

Translation.findById(idTranslation).populate({
        path: 'translation..idVideo',
        model: 'TranslationVideo'
    });

我希望填充 idVideo,以便我可以返回所有包含的数据,但我有:

"data": [
    {
       "type": "translations",
        "id": "5cc3fa08c2d98a3ac8e4889a",
        "translation": [
            [
                {
                   "x": "999",
                   "y": "999",
                   "width": "555",
                   "height": "555",
                   "idVideo": "5cc401f319bac9285ce0a235"
                 },
                 {
                    "x": "111",
                    "y": "111",
                    "width": "666",
                    "height": "666",
                    "idVideo": "5cc401f319bac9285ce0a235"
                 }
            ]
        ],
    }
]

解决方案

感谢 Moad Ennagi 提供的解决方案。 我刚刚编辑了他的解决方案,使其与 ASYNC/AWAIT 一起使用。

  static async findByIdAndPopulateVideos(idTranslation) {
    let count;
    let arr = [];

    if (!(count = await Translation.findById(idTranslation))) {
      return;
    }
    for (let i = 0; i < count.translation.length; i++) {
      arr.push(`translation.${i}.idVideo `); // Don't delete the last space !
    }
    return await Translation.findById(idTranslation).populate({
      path: arr.join(''),
      model: 'TranslationVideo'
    });
  }

最佳答案

您需要指定子数组的位置,然后填充其中的对象:

Translation.findById(idTranslation).populate('translation.0.idVideo')

这适用于第一个(子数组 [0]),如果你想填充其他子数组,你需要在数组内循环,我不认为 mongoose 带有任何内置位置运算符( $[] 作为在 mongoDB 原生客户端中)。
循环示例
这是一个完整的工作示例,我尝试模仿您的模式:

const fooSchema = new mongoose.Schema({
    name: String
  });
const Foo = mongoose.model('Foo', fooSchema);
const barSchema = new mongoose.Schema({
    x: String,
    y: String,
    fooId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Foo'
    }
  });
const Bar = mongoose.model('Bar', barSchema);
const totoSchema = new mongoose.Schema({
    bar: [[barSchema]]
  });
const Toto = mongoose.model('Toto', totoSchema);

// seeds
let foo = new Foo({name: 'foo'});
let bar, bar2;
foo.save().then(val => {
  bar = new Bar({x: '1', y: '1', fooId: val._id});
  bar2 = new Bar({x: '2', y: '2', fooId: val._id});
  toto = new Toto({bar: [[bar, bar2], [bar, bar2]]}).save(); // pushing the same objects(bar and bar2) out of lazyness
});

// A find query with a loop to construct paths to be populated
  Toto.findById(/* totoId */)
    .exec()
    .then(toto => {
      let arr = [];
      for(let i = 0; i <= toto.bar.length; i++) { // length of the array (1st dimension)
        arr.push(`bar.${i}.fooId `); // constrtucting the path
      }
      toto.populate(arr.join(''), (err, doc) => {
        if(err) throw err;
        else console.log(toto.bar);
      });
    })
    .catch(err => console.log(err));

/* Output
[
  [
    {
      "_id":"5cc472cd90014b60f28e6cb4",
      "x":"1",
      "y":"1",
      "fooId":{"_id":"5cc472ca90014b60f28e6cb3","name":"foo","__v":0}
    }, 
    {
      "_id":"5cc472cd90014b60f28e6cb5",
      "x":"2",
      "y":"2",
      "fooId": {"_id":"5cc472ca90014b60f28e6cb3","name":"foo","__v":0}
    }
  ], 
  [
    {
      "_id":"5cc472cd90014b60f28e6cb4",
      "x":"1",
      "y":"1",
      "fooId": {"_id":"5cc472ca90014b60f28e6cb3","name":"foo","__v":0}
    }, 
    {
      "_id":"5cc472cd90014b60f28e6cb5",
      "x":"2",
      "y":"2",
      "fooId": {"_id":"5cc472ca90014b60f28e6cb3","name":"foo","__v":0}
    }
  ]
]

*/

我希望这有帮助;)

关于arrays - Mongoose - 填充二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55878496/

相关文章:

javascript - 如何在 Javascript 中将查询字符串传递到 Google Sheets API v4

php - PHP 对象数组

arrays - Swift 3 - 检查数组中是否存在字符串并对其进行排序

python - 在 Python 中绘制向量数组 (pyplot)

node.js - 将 Webm 转码为音频文件 (fluent-ffmpeg)

javascript - 在 Meteor React 客户端中显示所有用户

node.js - Mongoose 辅助方法没有 findOne 方法?

node.js - 在带有 Mongoose (NodeJS) 的 MongoDB 中,如何查询(查找)填充字段?

javascript - 在 NodeJS 中进行 urldecode (php) 的最佳方式

node.js - Mongoose 嵌套架构 CastError