Reputation: 417
I've three mongoose models
When the user likes something it get saved in the Liked collection. But what I want to do is. Make a query that gives 10 available product the user hasn't liked before and is not his own product. I can't figure out how to make this possible in one query. Would it be possible?
User:
{
password: String,
type: {
type: String,
enum: ['user', 'admin'],
required: true,
default: "user"
},
firstName: {type: String},
middleName: {type: String},
lastName: {type: String},
gender: {type: String},
profilePicture: {type: Object},
setOwnProfilePicture: {type: Boolean, default: false},
facebook:{
id: {type: String},
token: {type: String}
}
}
Product:
{
condition: {
type: String,
enum: ['Als nieuw', 'Goed', 'Redelijk', 'Matig'],
required: true,
default: "Goed"
},
type: {
type: String,
enum: ['Ruilen', 'Doneren'],
required: true,
default: "Ruilen"
},
zipCode: {type: String},
houseNumber: {type: String},
distance: {type: Number},
likes: {type: Number, default: 0},
dislikes: {type: Number, default: 0},
title: {type: String},
description: {type: String},
owner: {type: Schema.ObjectId},
images: { type : Array , "default" : [] }
}
Liked:
{
ownerProductID: {type: Schema.ObjectId},
productID: {type: Schema.ObjectId},
liked: Boolean
}
UPDATE:
I find out what query to use, but in the result I have a field called liked
but I want to filter this out, so I don't get any extra values in my result.
The query I use now:
db.products.aggregate(
// Pipeline
[
// Stage 1
{
$match: {'owner': {$ne: ObjectId("583f2f33ee975f4e8560b9fe")}}
},
// Stage 2
{
$lookup: {
"from" : "likes",
"localField" : "_id",
"foreignField" : "productID",
"as" : "liked"
}
},
// Stage 3
{
$match: {'liked.ownerProduct': {$nin: [ObjectId("585834609bb1aa1cbe98257b")]}}
},
// Stage 4
{
$limit: 10
},
]
);
Upvotes: 0
Views: 3196
Reputation: 417
I managed to get the result I wanted. By using this query:
db.products.aggregate(
[
{
$match: {'owner': {$ne: ObjectId("583f2f33ee975f4e8560b9fe")}}
},
{
$lookup: {
"from" : "likes",
"localField" : "_id",
"foreignField" : "productID",
"as" : "liked"
}
},
{
$match: {'liked.ownerProduct': {$nin: [ObjectId("585834609bb1aa1cbe98257b")]}}
},
{
$limit: 10
},
{
$project: {
_id: 1,
owner: 1,
zipCode: 1,
title: 1,
description: 1,
houseNumber: 1,
images: 1,
dislikes: 1,
likes: 1,
type: 1,
condition: 1
}
},
]
);
Upvotes: 1
Reputation: 15244
Use aggregate to filter on multiple levels.
Assuming you have the USER_OBJECTID
, first filter products on owner, then join the collection with Liked
and filter again with user ID.
db.Product.aggregate([
{$match: {'owner': {$ne: '<USER_OBJECTID>'}}},
{$lookup: {
from: 'liked',
localField: '_id',
foreignField: 'productID',
as: 'likes'
}
},
{$match: {'likes.userID': {$nin: [<USER_OBJECTID>]}}},
{$limit: 10}
])
Upvotes: 2