MongoDB: How to remove all documents matching a query and return their ids - mongodb

With MongoDB, is it possible to specify a query and removes all matching documents while returning the documents' ids (alternatively the whole document)?
I found "How to get removed document in MongoDB?" that explains how remove a single document and return it using findAndModify. However, I need to remove a bunch of documents at once.
I'm ok with a solution involving the aggregation pipeline as long as it fulfils the requirements.
I'm using the offical C# driver, but solutions in JS are ok.

Related

which branches of a mongodb $or query were satisfied to include a document in the set returned?

Say I have a mongo $or query, something like { $or: [query1, query2, ... queryN] }, where each embedded query could be complex. Upon executing the query, a set of documents matching one or more of the embedded queries is returned. I would like to know which of the N embedded queries was satisfied for each document in the returned set, perhaps by adding a new field that I specify, eg. marks, into each returned document that would hold a list of the indexes of whichever of the queries was satisfied. I need this information to indicate how each document was identified in my application's interface.
I realize I could inspect the set once it is returned and determine the queries that were satisfied, but these queries could be arbitrarily complex and expensive to inspect - besides, this must have already been done inside mongo itself while doing the search.
I also realize I could run each of the N queries sequentially and then mark and merge the results into a growing set, but I want to save that overhead by running a single query instead of N queries.
And I realize that Mongo will certainly stop once the first satisfying query is found for each document, so I may not be able to get the complete set, but then I would at least like some assurance that the queries are executed in a certain order, say 1...N, and each document could be marked with its first satisfying index.
Does anyone know if there's a mechanism in Mongo that can do this?
You can use aggregation.
Use $addFields to add a new field for each query.
You could either $match first, and then add the fields, or add the fields first and on the added fields.

MongoDB: Recommended schema for search in trees

Currently I have a tree with various depth that contains user's documents.
John\folder1\sub-folder2...\document
Peter\folder1...\document
But as I can see Mongo does not support indexes in nested documents.
I tried to de-normalize my DB to User\documents with children ids. But it seems search would search whole collection, not only documents for given app-user.
should I create collection for every app user?
What is the better solution to use built in Mongo aggregation methods?
You need to use only one collection and not create collection for every user.
Using aggregation first thing you would do is a match by userId which filters all the documents by that user and then do any aggregation operations.
Aggregation in mongo is pipeline. Documents move from one operation to another.
So if you do match on userId then only those documents would be chosen and the next aggregation operation will get only those documents which matches the userId. So your aggregation is still faster.

Can an ordered array inside a document with MongoDB be guaranteed safe to maintain order in production [duplicate]

Simple question, do arrays keep their order when stored in MongoDB?
yep MongoDB keeps the order of the array.. just like Javascript engines..
Yes, in fact from a quick google search on the subject, it seems that it's rather difficult to re-order them: http://groups.google.com/group/mongodb-user/browse_thread/thread/1df1654889e664c1
I realise this is an old question, but the Mongo docs do now specify that all document properties retain their order as they are inserted. This naturally extends to arrays, too.
Document Field Order
MongoDB preserves the order of the document fields following write operations except for the following cases:
The _id field is always the first field in the document.
Updates that include renaming of field names may result in the reordering of fields in the document.
Changed in version 2.6: Starting in version 2.6, MongoDB actively attempts to preserve the field order in a document. Before version 2.6, MongoDB did not actively preserve the order of the fields in a document.

MongoDB bulk API: Finding out whch bulk updates matched

I'm doing multiple updates in a single bulk. Note: they are updates, not upserts. The problem doesn't allow it. Is there a way to find out which commands form the bulk matched (or didn't)?
From what I saw in the manual, you can only find the number of matches from BulkWriteResult, not which one matched, but I thought I'd ask anyway. Thanks for the help.
The BulkWriteResult doesn't contain this information and, as of MongoDB 2.6.3, there's no way to obtain it from the execution of the bulk operation. Of course, since you specify the criteria to determine which documents are updated, you can find out which documents are updated from the results of a find query with the same criteria. as long as the documents don't change in between. During a multistage bulk operation, you might change what documents match the update.

List of updated documents

Is there a way to update (or delete) many documents matching a certain criteria and get the list of IDs of actually updated/deleted documents (or some other fields of those documents)? I cannot simply query the documents matching my criteria beforehand because I need kinda atomicity for this operation. And I can't use findAndModify because it can only process one document at a time which is too slow because of round-trips. Suggestions?
MongoDB only supports atomic operations on a single document.
http://www.mongodb.org/display/DOCS/Atomic+Operations
The only way to do this is to do what you said you didn't one to:
First query the collection to find id's for our query:
db.things.find({"name":"john"}, {_id:1});
Then, use the same query to remove:
db.things.remove({"name":"john"}, {_id:1});
Not ideal, and not atomic, but it's as good as you're going to get in this scenario.