簡體   English   中英

如何在 2 map 函數中等待並從 mongoDB 檢索文件

[英]How to await inside 2 map functions and retrieve documents from mongoDB

我需要對返回如下內容的 API 執行一些修改:

[
  {
    "_id": "0000000000000000001",
    "name": "Random name",
    "categories": [
        "5eb8548330550e017f8902e6",
        "5eb2548630550e117f8909eb",
        "5eb6548930550e017f8909e9"
    ]
  },
  {...},
]

每個結果的類別都作為各自文檔的 ID 返回。 我需要操縱結果,以便每個對象的類別字段都有一個對象數組,每個 object 都有其類別的 ID 和名稱。 我舉例說明結果應該是什么:

[
  {
    "_id": "0000000000000000001",
    "name": "Random name",
    "categories": [
      {"_id": "5eb8548330550e017f8902e6",
      "name": "Category 1"},
      {"_id": "5eb2548630550e117f8909eb",
      "name": "Category 2"},
      {"_id": "5eb6548930550e017f8909e9",
      "name": "Category 3"},
    ]
  },
  {...},
]

我需要使用純 JS 來做到這一點,到目前為止,這是我所做的,但它返回一個未定義的數組:

const resultArray = await Promise.all(
  searchResults.map(async (item) => {
    item.categories.map(async (categoryId) => {
      return await CategoryType.find({ _id: categoryId});
    });
  })
);

目前,我正在嘗試為類別字段中的每個 id 獲取每個類別文檔。 我敢打賭我得到一個未定義數組的原因是我以錯誤的方式處理異步但無法弄清楚如何。

嚴格回答你的問題:你缺少同步(因為Array.prototype.map 'ignores' async):

const resultArray = await Promise.all(
  searchResults.map(async (item) => {
    const promises = item.categories.map(async (categoryId) => {
      // you dont want find, but findOne btw
      return await CategoryType.findOne({ _id: categoryId});
    });
    const categories = await Promise.all(promises)
    item.categories = categories
    return item
  })
);

這可以簡化為

const resultArray = await Promise.all(
  searchResults.map(async item => {
    item.categories = await Promise.all(item.categories.map(categoryId => {
      return CategoryType.findOne({ _id: categoryId})
    }))
    return item
  })
);

但正確的做法可能是使用populate

const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/dummy')

const Category = mongoose.model('Category', {
  name:String,
}, 'categories');
const X = mongoose.model('X', {
  name:String,
  categories: [{type: mongoose.Types.ObjectId, ref: 'Category'}]
}, 'xs');

;(async()=>{
  try {
  mongoose.set('debug', true)

  const xs = await X.find().populate('categories')

  console.log('xs : ', xs[0])
  } finally {
    mongoose.disconnect()
  }
})()

順便說一下,你會注意到 mongoose,在引擎蓋下使用find({ _id: {$in:[]}})它只發出一個請求(更好)而不是做多個findOne (就像你一樣)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM