Make nested queries in MongoDB 3.0.7 - mongodb

I have sub-events belonging to events belonging to an user, and I know the user's username - how do I get a list of the sub-events?
Is this going in the right direction? Or is it completely off?
db.subevents.find({_id: {$in:
db.events.find({_id: {$in:
db.users.find({"username":"userx"},{_id:1})}},{_id:1})}})
Edit: Here is a sample of the data structure:
/* Event */
{
"_id" : "XjhAqqNBkezKY3mdN",
"name" : "My event",
"userId" : "FiKsAAAgBb7cNoPH7"
}
/* Subevent */
{
"_id" : "WkYAqBXNpJryp7rum",
"name" : "The subevent",
"eventId" : "hQXNzX3jbWppbAYFH"
}
/* User */
{
"_id" : "RTHh5srhLMQp625zF",
"username" : "userx"
}

Following profesor79's advice to use three different calls, I put together this solution to get all the sub-events belonging to the user:
var userIds = db.users.find({"username":"userx"}).map(function(user) {
return user._id;
});
var eventIds= db.events.find({userId: {$in:userIds}}).map(function(event) {
return event._id;
});
db.subevents.find({eventId:{$in:eventIds}});

The only way is to make 3 ddifrent calls in mongo 3.0.7
GetUSerData
GetEventData
GetSubEventData
As you have relational schema here - this should be easy.
You could improve schema and remove subEvent collection by embedding subEvents documents into one events document
EDIT
/* Event */
{
"_id" : "XjhAqqNBkezKY3mdN",
"name" : "My event",
"userId" : "FiKsAAAgBb7cNoPH7"
"subewents" : [{
"_id" : "WkYAqBXNpJryp7rum",
"name" : "The subevent",
"eventId" : "hQXNzX3jbWppbAYFH"
}, {
"_id" : "WkYAqBXNpJryp7rum2",
"name" : "The subevent2",
"eventId" : "hQXNzX3jbWppbAYFH"
}, {
"_id" : "WkYAqBXNpJryp7rum",
"name" : "The subevent",
"eventId" : "hQXNzX3jbWppbAYFH"
}
]
}
/* User */
{
"_id" : "RTHh5srhLMQp625zF",
"username" : "userx"
}

Related

Add field to every document with existing data (move fields data to new field)

I have almost no experience in SQL or noSQL.
I need to update every document so that my fields "Log*" are under the new field "Log"
I found some help from this StackOverflow, but I am still wondering how to move the data.
Thank you very much
Original document
// collection: Services
{
"_id" : ObjectId("5ccb4f99f4953d4894acbe79"),
"Name" : "WebAPI",
"LogPath" : "Product\\APIService\\",
"LogTypeList" : [
{
"Name" : "ApiComCounter",
"FileName" : "ApiComCounter.log"
},
{
"Name" : "ApiService",
"FileName" : "ApiService.log"
}
]
}
Final Document
// collection: Services
{
"_id" : ObjectId("5ccb6fa2ae8f8a5d7037a5dd"),
"Name" : "InvoicingService",
"Log" : {
"LogPath" : "Product\\APIService\\",
"LogTypeList" : [
{
"Name" : "ApiComCounter",
"FileName" : "ApiComCounter.log"
},
{
"Name" : "ApiService",
"FileName" : "ApiService.log"
}
]
}
}
This requires MongoDB 4.2 or higher:
db.<collection>.updateMany({}, [
{$set: {"Log.LogPath": "$LogPath", "Log.LogTypeList": "$LogTypeList"}},
{$unset: ["LogPath", "LogTypeList"]}
])

MongoDB Check if a Collection contains a Key

I am using the MongoDB Async Driver to create a little Program were i have to save a User-Profile in the Database.
So i have a Database looking like this
`{
"_id" : ObjectId("5a1743f086060f1bbc319cdb"),
"id" : "aUser1",
"SomeArray" : {
"Name" : "SomeName"
}
}
{
"_id" : ObjectId("5a1743f186060f1bbc319cdc"),
"id" : "aUser2",
"SomeArray" : {
"Name" : "SomeName"
}
}
{
"_id" : ObjectId("5a1743f286060f1bbc319cdd"),
"id" : "aUser3",
"SomeArray" : {
"Name" : "SomeName"
}
}`
And now i try to figure out if the User 1 already has created a Profile.
Whith the old driver i would know how but with the , for me new, Async-Driver it sems a little bit tricky, do i have to make an Callback for this ?

meteor client find is not working due to $eq

I subscribed to my servers's publication as follows:
Template.observedQuestions.onCreated(function(){
var self = this;
self.autorun(function(){
self.subscribe('observedQuestionsFeed');
});
});
Now I need to fetch my data using helper function:
Template.observedQuestions.helpers({
observedQuestionsList : function(){
questions = Questions.find({
observedByUsers : {$exists: true,$elemMatch:{$eq:Meteor.userId()}}});
return questions;
}
});
but it does not work due to $eq being not recognised in minimongo.
How to solve it?
doc sample:
{
"_id" : "rP4JP8jkprwwi3ZCp",
"qUserId" : "NLLW3RBXqnbSGuZ3n",
"type" : "question",
"date" : ISODate("2016-02-13T11:23:10.845Z"),
"subject" : "test",
"question" : "test",
"replies" : [
{
"rID" : "LphcqKnkTHf25SCwq",
"rUserID" : "NLLW3RBXqnbSGuZ3n",
"date" : ISODate("2016-02-13T11:23:10.847Z"),
"answer" : "reply1."
},
{
"rID" : "HxaohnEgxwNJLtf2z",
"rUserID" : "NLLW3RBXqnbSGuZ22",
"date" : ISODate("2016-02-13T11:23:10.848Z"),
"answer" : "reply2"
}
],
"observedByUsers" : [ "Bi24LGozvtihxFrNe" ]
}
Judging from your sample Questions document, the field observedByUsers is a simple array which contains user IDs.
As a result, you could simply use the following query:
Questions.find({observedByUsers: Meteor.userId()});

How to publish only unique documents in Meteor?

So I have mongodb collection with documents that some of them have the same key (beatmapset_id):
{
"_id" : "fgq7SK7LnLbcFzgSb",
"beatmapset_id" : "59049",
"version" : "Hard",
"artist" : "UNDEAD CORPORATION",
"title" : "Yoru Naku Usagi wa Yume wo Miru",
"creator" : "Strawberry"
}
{
"_id" : "u7M8wibPwxuStNLSM",
"beatmapset_id" : "59049",
"version" : "jom's Taiko Muzukashii",
"artist" : "UNDEAD CORPORATION",
"title" : "Yoru Naku Usagi wa Yume wo Miru",
"creator" : "Strawberry"
}
{
"_id" : "ChRwdj7kbPL7oYgty",
"beatmapset_id" : "59049",
"version" : "jom's Taiko Oni",
"artist" : "UNDEAD CORPORATION",
"title" : "Yoru Naku Usagi wa Yume wo Miru",
"creator" : "Strawberry"
}
How do I publish only unique documents? Something like this:
Meteor.publish("beatmaps", function() {
return Beatmaps.find({ beatmapset_id: 1 }, { unique: true });
});
Now i solve this having 2 collections. One with all documents and one where I removed those documents with this code:
db.beatmaps.ensureIndex({ beatmapset_id: 1 }, { unique: true, dropDups: true });
But it's slow and when my first collection updates I also need to update second as well. I'm sure it can be done more consistent way.

MongoDB .Net driver 2.0 Builders Filter (field to array comparison)

I need to get all usernames from "followingList.username" and compare with
posts' usernames, if there any match need to add that one to an array.
Person Model
{
"_id" : ObjectId("554f20f5c90d3c7ed42303e1"),
"username" : "fatihyildizhan",
"followingList" : [
{
"_id" : ObjectId("55505b6ca515860cbcf7901d"),
"username" : "gumusluk",
"avatar" : "avatar.png"
},
{
"_id" : ObjectId("58505b6ca515860cbcf7901d"),
"username" : "yalikavak",
"avatar" : "avatar.png"
},
{
"_id" : ObjectId("58305b6ca515860cbcf7901d"),
"username" : "gumbet",
"avatar" : "avatar.png"
}
]
}
Post Model
{
"_id" : ObjectId("554f2df2a388R4b425b89833"),
"username" : "yalikavak",
"category" : "Summer",
"text" : "blue voyage with yacht"
},
{
"_id" : ObjectId("554f2df2a388P4b425b89833"),
"username" : "yalikavak",
"category" : "Winter",
"text" : "is coming ..."
},
{
"_id" : ObjectId("554f2df2a388K4b425b89833"),
"username" : "gumbet",
"category" : "Fall",
"text" : "there are many trees"
}
I try to get result code block as below but couldn't figure it out.
var filter = Builders<Post>.Filter.AnyEq("username", usernameList);
var result = collection.Find(filter).ToListAsync().Result;
Can you help me with this?
Thanks.
The logic is flipped, what you need is an $in query if I understand your use case correctly:
var filter = Builders<Post>.Filter.In("username", usernameList);
var result = collection.Find(filter).ToListAsync().Result;
In your case, username is a simple field and you want to match against a list of candidates. AnyEq is used to check that, from an embedded list of complex objects, at least one matches a criterion. That still translates to a simple query in MongoDB, but requires to 'reach into' the object which needs a more complicated syntax.