Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composition in mongo query (SQL sub query equivalent)

I have a couple of collections, for example;

members
   id
   name
   //other fields we don't care about
emails
   memberid
   //other fields we don't care about

I want to delete the email for a given member. In SQL I could use a nested query, something like;

delete emails
where memberid in (select id from members where name = "evanmcdonnal")

In mongo I'm trying something like this;

db.emails.remove( {"memberid":db.members.find( {"name":"evanmcdonnal"}, {id:1, _id:0} ) )

But it returns no results. So I took the nested query and ran it on it's own. The issue I believe is that it returns;

{
    "id":"myMadeUpId"
}

Which - assuming inner queries execute first - gives me a query of;

db.emails.remove( {"memberid":{ "id""myMadeUpId"} )

When really I just want the value of id. I've tried using dictionary and dot notation to access the value of id with no luck. Is there a way to do this that is similar to my attempted query above?

like image 729
evanmcdonnal Avatar asked Aug 06 '14 18:08

evanmcdonnal


People also ask

How do I create a nested query in MongoDB?

MongoDB Nested Query Match on a Nested Field You can use the dot notation (“field. nestedField”) to specify query criteria for fields in embedded/nested documents. For queries that use dot notation, fields and nested fields must be enclosed in double-quotes.

How do I join two collections in MongoDB?

For performing MongoDB Join two collections, you must use the $lookup operator. It is defined as a stage that executes a left outer join with another collection and aids in filtering data from joined documents. For example, if a user requires all grades from all students, then the below query can be written: Students.

What is the select query in MongoDB?

What is the select query in MongoDB? Running SQL statements against a MongoDB collection. An SQL SELECT statement typically retrieves data from tables in a database, much like a mongo shell find statement retrieves documents from a collection in a MongoDB database.

Does MongoDB use query?

MongoDB queries provide the simplicity in process of fetching data from the database, it's similar to SQL queries in SQL Database language. While performing a query operation, one can also use criteria or conditions which can be used to retrieve specific data from the database.


2 Answers

As forEach() way didn't work for me i solved this using:

var plzDeleteIds = db.members.find({ "name" : "evanmcdonnal" }, { "id" : 1 }).toArray();
var aux = plzDeleteIds["0"];
var aux2 = aux.map(function(u) { return u.name; } );
db.emails.remove({ "memberid" : { "$in" : aux2 } });

i hope it help!

like image 21
Wilmer González Avatar answered Sep 30 '22 10:09

Wilmer González


Let's see how you'd roughly translate

delete emails where memberid in (select id from members where name = "evanmcdonnal")

into a set of mongo shell operations. You can use:

db.members.find({ "name" : "evanmcdonnal" }, { "id" : 1 }).forEach(function(doc) {
    db.emails.remove({ "memberid" : doc.id });
});

However, this does one remove query for each result document from members. You could push the members result ids into an array and use $in:

var plzDeleteIds = db.members.find({ "name" : "evanmcdonnal" }, { "id" : 1 }).toArray();
db.emails.remove({ "memberid" : { "$in" : plzDeleteIds } });

but that could be a problem if plzDeleteIds gets very, very large. You could batch. In all cases we need to do multiple requests to the database because we are querying multiple collections, which always requires multiple operations in MongoDB (as of 2.6, anyway).

The more idiomatic way to do this type of thing in MongoDB is to store the member information you need in the email collection on the email documents, possibly as a subdocument. I couldn't say exactly if and how you should do this since you've given only a bit of your data model that has, apparently, been idealized.

like image 165
wdberkeley Avatar answered Sep 30 '22 09:09

wdberkeley