Show only collections which have documents inside in MongoDB - mongodb

Is it possible to get the list of the collections name which have at least one document?
I mean to not list the collections which don't have any document.

listCollections command allows filtering but the filters must be over the returned fields, and I don't see any field that returns the size of the collection.
Therefore you most likely need to query each collection with a find to find out if it has any documents.

Related

Is the Firestore collection write limit (imposed by sequentially-updated indexed fields) affected by collection-group queries?

From how I understand it, if a collection has a monotonically-increasing indexed field, a write limit is imposed on that collection. If that collection is split into two separate collections, each collection would have its own write limit. However, if we split that collection into two separate collections but give them the same name (putting them under different documents), would they still have their own independent write limits if the monotonically-indexed field was part of a collection-group query that queried them both together?
No, that's not the way it works. A collection group query requires its own index, and the limit you're talking about is the write rate of the index itself, not the collection. Each collection automatically indexes fields from documents for just that specific collection, but that would not apply the collection group queries that span collections.
Note that the documentation states the limit as:
Maximum write rate to a collection in which documents contain sequential values in an indexed field
On a related note, disabling the indexing for a specific field on a collection allows you to bypass the normal monotonic write limits for that one field on that collection because it's no longer being indexed.

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.

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

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.

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.

Listing fields in a mongodb object

I am developing a system where items can be shared with other users via an access key. I'm storing the access keys as fields within a shareinfo object (embedded within the item's document), as shown below:
shareinfo:{
........
<nth key>: <permissions object - may be complex and large>
........
}
When an item is accessed I check shareinfo.key and find if its valid or not.
Currently, to list the keys I am loading (in Java) the entire shareinfo object in memory and running keySet() on it to retrieve and return the keys while the rest of the data is wasted.
Here's the problem: I want to get the list of keys (i.e. object field names) without the accompanying data (because in some cases the permissions object is noticeably large).
I could not find any query in the mongodb docs for such a query. I want to know whether it's possible or not? Or is there an optimized way to load the list of field names into the application without the accompanying field values?
I had the same issue when trying to understand the structure of an existing mongodb database using the mongodb shell. Then I found that I can use the JavaScript function Object.keys() to retrieve an array of the object fields. (Tested with MongoDb 2.4.2)
Object.keys(db.collection.findOne())
MongoDB has a schema-less design, which means that any document could have different fields contained within it from any other document. To get an exhaustive list of all the fields for all the documents, you would need to traverse all the documents in the collection and enumerate each field. For any reasonably sized collection this is going to be an extremely expensive operation.
There are a couple of helpers that make this more simple: Variety and schema.js . They both allow you to limit the documents inspected, and they report on coverage as well. Both amount to doing a map/reduce on the collections, but are at least simpler than having to write one yourself.
If you are just looking for top-level fields across all documents (don't care about sub-fields and all the details statistics provided by variety)
Here is the one-liner
db.things.aggregate([{$project: {arrayofkeyvalue: {$objectToArray: "$$ROOT"}}}, {$unwind:"$arrayofkeyvalue"}, {$group:{_id:null, allkeys:{$addToSet:"$arrayofkeyvalue.k"}}}])