简体   繁体   中英

Mongoose: how to check if a value is in the array of a model, and append or delete it from array

I'm writting mongoose in Node.js (ES6).

I have a model Channel that have an array attribute subscribers . My goal is simply to check whether an element is in this array. If yes, delete it. If not, append it.

The schema for the Channel model is like this:

import { gql } from 'apollo-server-express';

export const Channel = gql`
type Channel {
    "Name of the channel, this is the full path."
    id: ID!
    name: String!
    path: String!
    subscribers: [String]
}
`

The definition of the Channel model:

import mongoose from 'mongoose';
import {Address} from './Address.js';
export const Channel = mongoose.model('Channel',
    {   
        id: mongoose.SchemaTypes.ObjectId,
        name: String,
        path: String,
        subscribers: [String],
    });

Referring to this post , I have written the following function:

async function updateChannelSubscriber(channel_path, user_id, action){
    // 1. check whether this user_id is in subscribers of this channel
    const alreadyExistFlag = await Channel.find({
        path: channel_path,
        subscribers: { "$in" : [user_id]},
    });

    
    // 2. If yes, remove it; else, append it
    if (alreadyExistFlag === undefined){
        await Channel.findOneAndUpdate({
            path: channel_path,
        }, {
            $push : {subscribers: user_id}
        })
    } else {
        await Channel.findOneAndUpdate({
            path: channel_path,
        }, {
            $poll : {subscribers: user_id}
        })
    }
    
}

I tried calling this function by passing:

{
    channel_name: ",Books,",
    user_id: "1234",
    preference_type: ALL_MESSAGES // A enum type, not important
}

However I got this error:

 "message": "Cast to ObjectId failed for value \"1234\" at path \"subscribers\" for model \"Channel\"",

change your approach, I didn't heard about $poll that you use in the query, is your mean $pull ? but just try like this

async function updateChannelSubscriber(channel_path, user_id, action) {
  // 1. check whether this user_id is in subscribers of this channel
  const alreadyExistFlag = await Channel.findOne({ path: channel_path });
  // 2. If yes, remove it; else, append it
  if (alreadyExistFlag) {
    alreadyExistFlag.subscribers = alreadyExistFlag.subscribers.filter(
      (item) => item != user_id
    );
  } else {
    alreadyExistFlag.subscribers.push(user_id);
  }
  await alreadyExistFlag.save();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM