How to search from list ObjectID in MongoDB - mongodb

I'm having a "ClubFollower" schema like below:
const ClubFollower = new Schema({
id_club:{
required:true,
type:String,
trim:true,
unique:true
},
followers:[
{
_id:false,
id_follower:ObjectId("xxxxxxxxxxxx"),
follower_type:String // 'club' | 'user'
}
]
});
each follower has many information such as:name, phone, email , etc... the question is how do I search a follower by name, phone, email ... with this schema. I dont think loop all item in follower array then findById with each id_follower and compare search key with email, phone... is good solution

You can use Aggregation Pipeline. First you $match on id_club, then you $unwind followers and $lookup followers from their collection based on id_follower. Finally, you can use other stages to filter based on followers' attributes.
You could also search from the other side. Have your followers collection store the clubs they are part of and match against that collection instead.

Related

How do you fetch users posts with accurate sorting order, using mongo db, in a facebook like application

I am building a social media application similar to facebook with mongodb, I will like the users post feeds to be sorted by
if user is following the author of the post
how popular the post is, for example, the number of likes and the number of comments
the location of the user, (if it is same with the author of the post)
sort by the value of (count of "like reaction" for last 6 months - count of value of "sad reaction" for last 6 months)
lastly the time at which the post was created
here is the schema of the database
user: {
_id: mongoId
username: string
location_id: ref location _id
}
post: {
_id: mongoId
content: string
author: ref user _id
}
comment: {
_id: mongoId
content: string
post: ref post _id
author: ref user _id
}
reaction: {
_id: mongoId
type: enum['like', 'love', 'sad']
post: ref post _id
author: ref user _id
}
follow: {
_id: mongoId
follower: ref user _id of the one who is following another
following: ref user _id of the one who is being followed another
}
location: {
_id: mongoId
country: string
}
i will like a mongo query that will fetch this posts in the order of the sort i mentioned, i will really appreciate any help at all, even though not all the sort values can be accomplished, just mention which ones can and how i can achieve that
I have tried using the $sort, $sortByCount, $group $sum and some other aggregate methods, but i am not getting the right order
I am expecting to see the posts fetched in desending order

How can I query for a subdocument full of objects in Mongo?

So I have a document with an unknown number of objects in it, each with 2 properties. It's a collection of friend lists, and I'm trying to confirm if someone has a friend with a certain username before I allow a user to send a request. I'm keeping the list of friends in a subdocument, like this:
>>all the _id and other properties<<, "ownerFriends":[{"friendId":"an id goes here", "friendUsername": "username"}, {"friendId":"another id", "friendUsername":"username2"}]
I'm trying to do a query that will return username2 if given that as input, but I don't know how to do that with dot notation because I think you need to know the specific property to look for, and these are heterodox amounts of friend objects in the ownerFriends property.
If you want to select the ownerFriend object that has username as the friendUserName you can use the following selector (assuming your collection is called Friends):
Friends.find({
"ownerFriends.friendUsername": "username2"
}, {
fields: { "ownerFriends.$": 1}
});
You can find a detailed explanation of how to query an array of objects based on a property here:
http://www.curtismlarson.com/blog/2015/08/08/meteor-mongodb-array-property-selector/
In summary you have an object that contains keys, one of whose values is an array of objects. You can perform queries on the arrays using $elemMatch In your case:
MyCollection.find({ ownerFriends: { $elemMatch: { friendUsername: searchString }}});
Although I think you'll need to also query on the current user's _id. Not knowing the details of your collection, I can only speculate with:
MyCollection.find({ userId: Meteor.userId(), ownerFriends: { $elemMatch: { friendUsername: searchString }}});

Publishing data with information from another collection in Meteor

I have two collections: Meta and the normal users collection. The Meta collection has the following structure:
{
userId: ObjectId,
contacts: [Array],
conversations: [Array]
}
Each user has a corresponding, distinct document in the Meta collection. Now I want to publish the users that belong in the current user's contacts or conversations array.
{
userId: 123,
contacts: ['a', 'b', 'c'],
conversations: ['a', 'e']
}
For user 123, I want to publish user profile data for users a, b, c and e. Basically all the distinct values of the contacts and conversations array.
I tried merging the array and using `_.uniq' on the new array inside the publish function but I need this to be reactive so when a user adds a new contact, the contact list can update reactively. Something tells me Mongo's aggregation framework can help but I'm not sure how to use it with Meteor. Any thoughts?
You can use the reactive-publish package (I am one of authors):
Meteor.publish('profiles', function (userId) {
this.autorun(function (computation) {
var meta = Meta.findOne({userId: userId}, {fields: {contacts: 1, conversations: 1}});
return Meteor.users.find({_id: {$in: meta.contacts.concat(meta.conversations)}}, {fields: {profile: 1}});
});
});
The important detail is that you have to limit the first query only to contacts and conversations fields, otherwise autorun would be rerun every time any field in the Meta document changes.
You should probably also add some checks, like what if corresponding Meta document does not exist. Or if fields (arrays) do not exist.

Meteor: How do you populate a field from one collection into another collection with _id field?

In mongo I have a document that stores pending userId's in a collaborators object array and looks like this:
researchThread {
_id: 4374583575745756
pending: {
collaborators: [
{
userId: '13745845754745753'
},
{
userId: '23755845854745731'
},
{
userId: '33755845653741736'
}]
}
}
The userId is the _id field for the user from the users collection. Each user also has a name and an email field.
How can I populate the name and email fields from the user collection, into this document for each user in the researchThread.pending.collaborators object array? And also, will the populated data be reactive when used in the templates?
Loop through each collaborator, find the relevant user document by searching the users collection for the id, and update the researchThread document with that information.
The data will be reactive if the researchThread collection is a Meteor.Collection which you're drawing from in your templates.
However, why do you want to copy the user data? Why not just have Meteor query the users collection based on the researchThread userId when you need the data in the template?

Put multiple fields in one index

When I have a collection of users, with a structure like this:
{
...
phone:"XXXXXXXXXX",
email:"XXXXXXXXXX",
...
}
Is there a way to put both the fields phone and email into one index, for example called contactinfos, so that I can query my user by their phonenumber OR by their email address like this:
db.users.find({contactinfos:"E-Mail-Address or Phonenumber"})
?
You don't need to create an aggregate field. You can query your collection with $or operator:
db.users.find( { $or: [ { email: "email#somethingc.com"}, { phone: "123456" } ] } );
This will find all documents with either e-mail OR phone.
You can then create a compound index on both fields to make the query faster (if you're using MongoDB 2.4).
If you're using MongoDB 2.6 you can take advantage of index intersection and create two separate indexes for those fields.