I'm making the followed/following rules to simulate a blog/social like app, but I want to suggest to to the users only people that are not following or followed by this user, but any combination haven't worked out yet. The Schema is:
const Follower = new mongoose.model('Follower', new mongoose.Schema({
sent: {
type: mongoose.Schema.Types.ObjectId,
ref: User,
required: true
},
received: {
type: mongoose.Schema.Types.ObjectId,
ref: User,
required: true
},
pending: {
type: mongoose.Schema.Types.Boolean,
required: true,
default: true
}
}))
So, if I already sent invitation, or if the user already sent me invitation, should be excluded from the list of suggestions to follow.
So, I select 100 id's from database, but not my id, of course:
const users = await User.find({ '_id': { $ne: id }}).select('_id').limit(100)
I put these id's on an array:
let ids = []
users.forEach(user => {
ids.push(user._id)
})
Now, I must exclude from this array of id's all users that already sent or received invitations by the user logged in, but the query returns empty:
// id from user logged in
const id = req.id
let followers = await Follower.find({
$or: [{sent: id}, {received: {$in: ids}}],
$or: [{sent: {$in: ids}}, {received: id}]
})
I've tried other queries, but to no avail. Any hints, suggestions?
I have not reproduce your specific schema but have you tested with:
Follower.find({
$and: [
{ $or: [{ sent: id }, { received: { $in: ids } }] },
{ $or: [{ sent: { $in: ids } }, { received: id }] },
],
});
Cause it seems that not using $and
is making the query ignore your second $or
. I've tested with sample data below:
const main = async () => {
await connectDB();
const Test = new mongoose.model(
"test",
new mongoose.Schema({
sent: {
type: Number,
required: true,
},
received: {
type: Number,
required: true,
},
})
);
function getRandomInt(max = 10) {
return Math.floor(Math.random() * max);
}
const sampleDatabaseSize = 100;
for (i = 0; i < sampleDatabaseSize; i++) {
await Test.create({
sent: getRandomInt(),
received: getRandomInt(),
});
}
id = 4;
ids = [1, 2, 3];
result = await Test.find({
$and: [
{ $or: [{ sent: id }, { received: { $in: ids } }] },
{ $or: [{ sent: { $in: ids } }, { received: id }] },
],
});
console.log(result);