skip to Main Content

Suppose in the listing(includes other attributes like title, price as well) i give a set of 20 members with their name and phone number.I need to automatically check whether these members already exists in the member list, if they exist then add return the price of the listing else add the member to the member list.
I am not able to define a particular schema for member model whether array or string or key value pair for member name and member phone number.if i define also i am not able to retrieve it from the database and compare it
So basically i want a member list like member 1 member2 … and when i create the listing these listing members should get compared with the members are return price if they exist else create a new member with that particular name and phone number

listing model

    const listingSchema = new Schema({
    title: { type: String },
    price: { type: Number },
    startDate: {
      type: Date,
    },
    currentMonth: { type: Number },
    endDate: {
      type: Date,
    },

    member: { type: String },
    phone: { type: Number },
    });

member model

    const memberSchema = new Schema({
      member: "String",
      phone: "Number",
    });

listing controller

    const newListing = new listing({
      title: req.body.title,
      price: req.body.price,
      startDate: req.body.startDate,
      currentMonth: req.body.currentMonth,
      endDate: req.body.endDate,
    member: req.body.member,
    });

    let member = newListing.member;
    // console.log(member);
    let present = await members.findOne([member]);
    console.log(present);

    member.forEach(async (e) => {
      // console.log(e);
      let existingMember = await members.findOne({ name: e });
      if (existingMember) {
        console.log("yes");
        console.log(req.body.price)
      } else {
        console.log("no");
        //createmember;
      }
    });

member.controller

    try {
    const newMember = new member({
      member: [{ name: req.body.name, phone: req.body.phone }],
    });
    console.log(newMember);
    // let savedMember = await newMember.save();
    // console.log(savedMember);
    return res.json({ message: "New Members Created!" });
    } catch (error) {
    console.log(error);
    res.status(404).json(error, "cannot create new member");
    }

2

Answers


  1. I guess you are trying to say is, if a member exists in the database, return the price of listing that includes that member, or create a new member.

    1. Update your Member model

    const memberSchema = new Schema({
      name: { type: String, required: true },
      phone: { type: Number, required: true, unique: true },  // unique phone numebrs
    });

    2. Update your Listing model

    const listingSchema = new Schema({
      title: { type: String },
      price: { type: Number },
      startDate: { type: Date },
      currentMonth: { type: Number },
      endDate: { type: Date },
      members: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Member' }]  // Array of Member references
    });

    Note: Add this if you dont have a lot of members cuz mongodb can only hold upto 16 mb data per document. If you have a lot of members in the listing then I would suggest you to make a different model and schema to store members of listingSchema.

    For eg: (only if you think your members field in you listingSchema will be a lot more and might exceed 16 mb limit per document).

    const membersOfListingSchema = new Schema({
      listing: { type: mongoose.Schema.Types.ObjectId, ref: 'Listing' },
      member: { type: mongoose.Schema.Types.ObjectId, ref: 'Member'}
    });

    By doing this, you can add as many members as you want per listing.

    3. Creating or Fetching members

    I really don’t understand what you are trying to do in listing controller but looking at your code of listing controller and what you have said (you said: i give a set of 20 members with their name and phone number). I have come up with this code:

    const createListing = async (req, res) => {
      try {
        const { title, price, startDate, currentMonth, endDate, members } = req.body;
        /* as you said 'members' is an array of { name, phone },
           for eg: members: [{name: "", phone: ""}, {name: "", phone: "", ...}]
        */
        
        let memberIds = [];  //store ObjectIds of members
        
        //check each member and either find or create them
        for (const memberData of members) {
        //use blukWrite if you are concerned about performance
          let existingMember = await Member.findOne({ name: memberData.name, phone: memberData.phone });
    
          if (!existingMember) {
            //create a new member if it doesnt exist
            const newMember = new Member({ name: memberData.name, phone: memberData.phone });
            existingMember = await newMember.save();
          }
    
          //add the ObjectId of the member to the list
          memberIds.push(existingMember._id);
        }
    
        //create the listing and reference the member ObjectIds
        const newListing = new Listing({
          title,
          price,
          startDate,
          currentMonth,
          endDate,
          members: memberIds //send the memberIds
        });
    
        const savedListing = await newListing.save();
        res.status(201).json(savedListing);
    
      } catch (error) {
        console.error(error);
        res.status(500).json({ error: 'Failed to create listing' });
      }
    };

    You don’t need to handle duplicate members cuz the phone field in memberSchema is set to unique. MongoDB will handle that.

    4. Fetch listings with members information

    Just use .populate()

    For eg:

    const listing = await Listing.findById(/*listing id*/).populate('members');

    Hope this helps you on what you want to achieve and make.

    Login or Signup to reply.
  2. First of all you would want to store name and number as separate records in member model.

    const memberSchema = new Schema({
      name: { type: String, required: true, unique: true },
      phone: { type: Number, required: true, unique: true }
    });
    

    The listing schema can store these references of the member ocjects using ObjectId. This is how you could keep the relationship between listing and member.

    const listingSchema = new Schema({
      title: { type: String },
      price: { type: Number },
      startDate: { type: Date },
      currentMonth: { type: Number },
      endDate: { type: Date },
      members: [{ type: Schema.Types.ObjectId, ref: 'Member' }]
    });
    

    Then you can check for existing members and add new if needed like so:

    const createOrUpdateListing = async (req, res) => {
      try {
        const membersFromRequest = req.body.members; // assuming req.body.members is an array of {name, phone}
        const memberIds = [];
    
        for (const member of membersFromRequest) {
          // Check if the member already exists in the database
          let existingMember = await Member.findOne({ name: member.name, phone: member.phone });
          
          if (!existingMember) {
            // Create new member if they don't exist
            const newMember = new Member({
              name: member.name,
              phone: member.phone
            });
            existingMember = await newMember.save();
          }
    
          memberIds.push(existingMember._id); // Collect ObjectId for the listing
        }
    
        // Create a new listing with the member references
        const newListing = new Listing({
          title: req.body.title,
          price: req.body.price,
          startDate: req.body.startDate,
          currentMonth: req.body.currentMonth,
          endDate: req.body.endDate,
          members: memberIds
        });
    
        const savedListing = await newListing.save();
        res.status(201).json(savedListing);
      } catch (error) {
        console.error(error);
        res.status(500).json({ message: 'Error creating listing' });
      }
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search