Gaurav
Gaurav

Reputation: 116

How to filter data from mongo collection subarray with subarray data of other collection

Baiscally making a node.js, mongodb add friends functionality where having the option of list user to add in friends list, sent friends request, accept friends request, delete friends request, block friends request.

Register Collection

const mongoose = require('mongoose');

const Schema = mongoose.Schema;


let Register = new Schema(
    First_Name:{
        type: String,
        required: true   
    },
    Last_Name: {
        type: String
    },
    Email: {
        type: String,
        unique: true,
        lowercase: true,
        required: true
    },
    Friends:[{type: String}],  
});

module.exports = mongoose.model('Register', Register);

Friends Collection

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
var ObjectId = require('mongodb').ObjectID;
let Friends = new Schema({
    Requester: {
        type: ObjectId,
        required: true
    },
    Recipients: [{Recipient:{type:ObjectId},Status:{type:Number}}],


}); 
module.exports = mongoose.model('Friends', Friends);

Inside Node.js Post API

var Register = require('../models/register.model');
var Friends =require('../models/friends.model');

router.post('/getdata',function(req,res)
{
let Email="[email protected]";

Register.findOne({ Email : Emails }, function(err, user) {

Friends.findOne({ Requester :user._id  }, function(err, user1) {

Register.find({$and:[{Friends:{$nin:[user._id]}},{_id:{$ne:user1.Recipients.Recipient}}]},function(err, user2) {

console.log("user2",user2);

//Here User2 data is not coming

//How to get data so can able to list user that is not added yet in FriendList

//Mainly user1.Recipients.Recipient this is not working because //Recipients is array so how can match all data with array, if i am //using loop then find return data scope ends on inside find closing //braces only.


//Any suggestion

 });

 });
});

Upvotes: 1

Views: 204

Answers (2)

Remy Kabel
Remy Kabel

Reputation: 1017

So if I have it correct, you want to do the following:

  1. Find a registration based on a given email
  2. Find the friends related to this user
  3. Find registrations that are not yet in the friend list of the user

Also, given what you've typed, I'm assuming A can be the friend of B, but that doesn't mean B is the friend of A.

While the data structure you currently have may not be optimal for this, I'll show you the proper queries for this:

var Register = require('../models/register.model');
var Friends =require('../models/friends.model');

router.post('/getdata',function(req,res) {
    const email = "[email protected]";

    Register.findOne({ Email: email }, function(err, user) { 
        if (err) {
             console.error(err);
             return;
        }

        Friends.findOne({ Requester: user._id }, function(err, friend) {
            if (err) {
                console.error(err);
                return;
            }

            const reciptientIds = friend.Recipients.map(function (recipient) {
                return recipient.Recipient.toString();
            });

            Register.find({Friends: { $ne: user._id }, {_id: { $nin: recipientIds }}, function(err, notFriendedUsers) {
                if (err) {
                    console.error(err);
                    return;
                }

                console.log(notFriendedUsers);
            });
        });
    });
});

P.S. This "callback hell" can be easily reduced using promises or await/defer

Upvotes: 1

Gaurav
Gaurav

Reputation: 116

Finally able to solve it, below is the solution

var Register = require('../models/register.model');
var Friends =require('../models/friends.model');

router.post('/getdata',function(req,res)
{
let Emails="[email protected]";

 Register.findOne({$and:[{ Email : Emails}] }, function(err, user) { 
              if (err) {
                   console.error(err);
                   return;
              }

              Friends
              .findOne({ Requester: user._id }, 
                    { _id: 0} )
              .sort({ Recipients: 1 })
              .select( 'Recipients' )
              .exec(function(err, docs){
                  docs = docs.Recipients.map(function(doc) { 
                    return doc.Recipient; });
                  if(err){
                      res.json(err)
                  } else {
                    console.log(docs,"docs");
                      Register.find({$and:[{Friends: { $ne: user._id }},{_id: { $nin: docs }},{_id:{$ne:user._id}}]}, function(err, notFriendedUsers) {
                        if (err) {
                            console.error(err);
                            return;
                        }

                        console.log(notFriendedUsers);
                    });

                  }
              })
            });

Upvotes: 0

Related Questions