mon goose проверьте, существует ли идентификатор, но этот идентификатор вложен в массив - PullRequest
2 голосов
/ 13 июля 2020

Когда я получаю новые оповещения, я хочу проверить, был ли уже записан идентификатор нового оповещения. Проблема в том, что этот идентификатор вложен в массив. Есть массив alertsDetails, который содержит объекты, и у этих объектов есть поле _ID, которое я хочу проверить. Я не знаю, как этого добиться. Я получил код ниже, но затем мне нужно перебрать результат, чтобы проверить существующее значение. Я уверен, что должен быть способ получше.

const mongoose = require('mongoose');

const { Schema } = mongoose;

const G2AlertsSchema = new Schema(
  {
    status: { type: String, required: true },
    openDate: { type: Date, required: true },
    alertType: { type: Array, required: true },
    severity: { type: Array, required: true },
    locationName: { type: Array, required: true },
    history: { type: Array, required: true },
    alertDetails: { type: Array, required: false },
    assignedTo: { type: Schema.Types.ObjectId, ref: 'user' },
  },
  {
    timestamps: true,
  },
);

const G2Alerts = mongoose.model('G2Alert', G2AlertsSchema);

module.exports = G2Alerts;

Это код, который я нашел на сайте mongodb. Я просто хочу посмотреть, существует ли только идентификатор. В основном, когда я получаю новые предупреждения, я получаю массив и перебираю его, я хочу проверить идентификатор каждого элемента на то, что находится внутри базы данных. Если он есть, переходите и go переходите к следующему. Если он новый, создайте новое предупреждение и сохраните его.

 const exists = await G2Alerts.aggregate([
    {
      $project: {
        exists: {
          $in: ['5f0b4f508bda3805754ab343', '$alertDetails._id'],
        },
      },
    },
  ]);

EDIT: Другое дело. Я получаю предупреждение eslint, в котором говорится, что я должен использовать итерацию массива вместо a для l oop. Проблема в том, что мне нужно использовать ожидание при поиске идентификатора предупреждения. Если я использую, уменьшаю или фильтрую, я не могу использовать ожидание. Если я использую asyn c внутри функции уменьшения или фильтрации, тогда он вернет обещания в или просто пустой массив.

Это работает на основе ответа, предоставленного Tom Slabbaert

  const newAlertsData = [];

  for (let item of alertData.data.items) {
    const exists = await G2Alerts.find({ 'alertDetails._id': `${item._id}` });
    if (exists.length === 0) {
      newAlertsData.push(item);
    }
  }

  if (newAlertsData.length !== 0) {......

Но это не

  const filteredAlerts = alertData.data.items.reduce((filtered, item) => {
    const exists = await G2Alerts.find({ 'alertDetails._id': `${item._id}` });
    if (exists.length === 0) {
      filtered.push(item);
    }
    return filtered;
  }, []);

введите описание изображения здесь

1 Ответ

2 голосов
/ 13 июля 2020

Вы не за горами, вот пример с правильным синтаксисом:

const exists = await G2Alerts.findOne({"alertDetails._id": '5f0b4f508bda3805754ab343'}});
if (!exists) {
    ... do something
}

Этого также можно достичь, используя aggregate со стадией $match вместо стадии $project или даже лучше countDocuments , который просто возвращает счетчик вместо всего объекта, если он вам не нужен.

Еще я хотел бы добавить, что убедитесь, что alertDetails._id - это Введите string так же, как string вместо $in. в противном случае вам нужно будет преобразовать их в ObjectId введите mon goose вот так:

new mongoose.Types.ObjectId('5f0b4f508bda3805754ab343')

И для Mon go:

import {ObjectId} from "mongodb"
...


new ObjectId('5f0b4f508bda3805754ab343')

РЕДАКТИРОВАТЬ

Попробуйте что-то вроде этого?

let ids = alertData.data.items.map(item => item._id.toString());
let existing = await G2Alerts.distinct("alertsDetails._id", {"alertsDetails._id": {$in: ids}});

const filteredAlerts = alertData.data.items.reduce((filtered, item) => {
    if (!existing.includes(item._id.toString())) {
        return [item].concat(filtered)
    }
    return filtered;
}, []);

Таким образом, вам нужно вызвать базу данных только один раз, а не несколько раз.

Окончательный код на основе предоставил ответ.

  const ids = alertData.data.items.map(item => item._id);
  const existing = await G2Alerts.find({ 'alertDetails._id': { $in: ids } }).distinct(
    'alertDetails._id',
    (err, alerts) => {
      if (err) {
        res.send(err);
      }
      return alerts;
    },
  );

  const filteredAlerts = alertData.data.items.reduce((filtered, item) => {
    if (!existing.includes(item._id.toString()) && item.openDate > dateLimit) {
      return [item].concat(filtered);
    }
    return filtered;
  }, []);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...