【问题标题】:Check array values, if are present in mongodb collection push into new array检查数组值,如果存在于 mongodb 集合中,则推送到新数组中
【发布时间】:2020-12-17 17:32:16
【问题描述】:

我通过 mongoose 直接连接到 mongodb,通过 dbConnect() 调用 mongoose db 文件,并且我的查询工作正常。问题在于我后来添加的标准数据库连接 (const { db } = await connectToDatabase();) 来查询我无法转换为可接受的猫鼬模式的集合。

我的代码在顶部:

import { connectToDatabase } from "../../utils/mongodb"
import dbConnect from '../../utils/dbConnect'

dbConnect();

export default async (req, res) => {
  const { db } = await connectToDatabase();

  try{ ...

我从 API 获取了一些 data 我需要遍历这个 data.title 并在 mongodb 集合“通道”(字段为“名称”)中执行 find(),以便仅保留与集合项的字段名称匹配的那些 data.title

我尝试的是这样的:

        var token = `https://www.googleapis.com/youtube/v3/subscriptions?part=snippet%2CcontentDetails&mine=true&maxResults=50&key=${process.env.GOOGLE_API_KEY}&access_token=${token}`;
        token = token.replace(/"/g, '');

        var url = await fetch(token);
        const subsData = await url.json();

        //* Save all followed channels names, imgs and ids in arrays
        var subsArray = [], idsArray = [], imgsArray = [];
        for(let i=0; i < subsData.items.length; i++){
          //* check the channel's name is in database
          // if ( Chann.findOne({ "name" : subsData.items[i].snippet.title }) ) {
          if ( db.channels.find({ name: subsData.items[i].snippet.title }) != null ) {
            idsArray.push(subsData.items[i].snippet.resourceId.channelId);
            subsArray.push(subsData.items[i].snippet.title);
            imgsArray.push(subsData.items[i].snippet.thumbnails.default.url);
          }
        }

但它会抛出:TypeError: Cannot read property 'find' of undefined

正如您从代码中看到的那样,我也尝试使用 mongoose,两者都在我的项目中进行了配置,但使用 mongoose 模式它根本没有做任何事情,好像 findOne 始终为真。所以它没有抛出任何错误但基本上没有工作,数组中的所有通道都被接受了。我想知道这是否是由于模式之间不完全匹配的原因,因为我从已经存在的 mongodb 数据中手动重新创建了模式“Chann”,而且我不是 100% 确定我在这里和那里正确地编写了数组的对象..

更新

如下所示,我将其更改为:

  var subsArray = [], idsArray = [], imgsArray = [];
  for(let i=0; i < subsData.items.length; i++){
  
  console.log("title "+subsData.items[i].snippet.title)
  
  const result = await db.collection("Channels").find({ name: subsData.items[i].snippet.title })
  console.log("result "+result)
  if(!result.length) {
    idsArray.push(subsData.items[i].snippet.resourceId.channelId);
    subsArray.push(subsData.items[i].snippet.title);
    imgsArray.push(subsData.items[i].snippet.thumbnails.default.url);
  }
}

但它记录的是 [object Object] ,如果我添加到查找行 .toArray() 它会变成 [object promise] 并且如果我尝试记录 JSON.stringify result 它会抛出 TypeError: Converting circular structure to JSON

【问题讨论】:

  • 我什至不知道,看起来很有趣。尽管我认为这里的问题是数据库调用,但实际上应该包含数组的 const 记录了一个空数组

标签: javascript node.js arrays mongodb mongoose


【解决方案1】:
db.channels.find({ name: subsData.items[i].snippet.title }) != null

这将无法按照您的使用方式工作。

db.channels.find({ name: subsData.items[i].snippet.title })

返回一个Promise,它永远不会是null

相反,您会想做类似的事情

const result = await db.channels.find({ name: subsData.items[i].snippet.title })
if(!result.length) {
   ...
}

您可以使用回调、Promises 或 async/await 来等待数据库结果,我的示例是使用 async/await,但有一些选项。

【讨论】:

  • 我得到“TypeError: Cannot read property 'find' of undefined”集合名称是带有上限 C 的 Channels,所以在代码中我使用了“db.Channels.find”
  • 但我认为我不能在循环中使用 await ?循环继续,等待累积,我猜,如果有办法在循环之前将所有集合“名称”值保存在数组中,我也许可以为循环的每个索引执行 if array.includes?
  • 如果我改用“db.collection("Channels").find”,它会推送所有频道,即使是那些与集合“名称”不匹配的频道。我正在调试结果,它似乎是一个对象,但是当我使用 JSON.stringify 时,它会抛出 TypeError: Converting circular structure to JSON
  • @m4tt 您可以在循环中使用 await 。 for 循环将暂停。看起来您可能直接使用 mongo 驱动程序,而不是 mongoose。如果您直接使用驱动程序,您将需要执行.find(...).toArray()。 Mongoose 会自动执行此操作。假设您使用的是 Mongoose,我写了答案。
  • 它确实有效,在我身边的 env.local 中是一个愚蠢的错误。请稍微编辑一下,以便我投票赞成并使其成为答案
【解决方案2】:

第一次检查-

if(subsData.items[i].snippet.title!= undefined && subsData.items[i].snippet.title!= null){
    // ....
}else{
    console.log(...);
}

【讨论】:

  • 我正在记录它并且值是好的
猜你喜欢
  • 2019-09-15
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 2021-01-19
  • 2018-10-08
  • 1970-01-01
相关资源
最近更新 更多