You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mongoose查询获取字符串数组格式的IP列表(非对象数组)

问题

我定义了如下Mongoose Schema:

const proxyIpSchema = new Schema<IProxyIp>({
      ip: { 
        type: String,
        required: true,
        //ignore duplicate ip
        unique: true,
      },
      port: { 
        type: Number,
        required: false,
        default: null
      },
      reason: {
        type: String,
        required: true,
        default: 'Unknown Detection.'
      }
    },
      {
        timestamps: true,
      }
    );

我希望查询所有IP属性,得到纯字符串数组格式(如[IP,IP,IP,IP]),而非[{ip: IP}]这样的对象数组。由于map函数会消耗后端算力,我不想使用这种方式。当前我通过以下代码从MongoDB获取IP并存入Redis,但希望优化:

//get all ips from mongo db and push to redis
await ProxyIp.find({}, { ip: 1 }).then(async (docs) => {

  docs.map(async (doc) => {
    await this.RedisClient?.sAdd(redisTable, doc.ip);
  });
  
}).catch((err) => {
});
优化方案

1. 直接用MongoDB的distinct获取纯IP数组

因为你的ip字段已经设置了unique: true,使用distinct方法可以直接从数据库层面返回去重后的纯IP字符串数组,完全避免后端处理对象数组的开销:

const ipList = await ProxyIp.distinct('ip');

这行代码直接得到[ip1, ip2, ip3...]格式的结果,无需任何额外转换。

2. 批量写入Redis,减少网络IO

原来的循环调用sAdd会发起多次Redis请求,换成批量写入,一次请求完成所有IP的添加,大幅降低网络开销:

try {
  const ipList = await ProxyIp.distinct('ip');
  if (ipList.length > 0 && this.RedisClient) {
    // 展开数组批量写入
    await this.RedisClient.sAdd(redisTable, ...ipList);
  }
} catch (err) {
  console.error('同步IP到Redis失败:', err);
}

3. 替代方案:用聚合操作生成数组(适合需要额外过滤场景)

如果后续需要对IP做过滤、筛选后再生成数组,可以用MongoDB聚合在数据库层面完成处理,返回纯数组:

const result = await ProxyIp.aggregate([
  // 可在这里添加$match做条件过滤
  { $group: { _id: null, ips: { $push: "$ip" } } },
  { $project: { _id: 0 } }
]);
const ipList = result[0]?.ips || [];

// 后续批量写入Redis逻辑同上

内容的提问来源于stack exchange,提问作者Rumira Daksith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:40:47