why a collection exists but can not find in show collections? - mongodb

In the mongo shell, I can find records from collection stat by using such commands:
use gm;
gm.stat.find({});
but stat is not listed in show collection results.

Any collection virtually exists all the time (i.e. you will not get an error saying that "you did not create a collection"). As soon as you insert the first document into a collection this will exist also physically (will be created on the disk). So if you really want to make sure a collection exists use:
db.getCollectionNames()
This will show you only the collections that had at least one document inserted into them, even if they are currently empty.
Once physically created, a collection can be deleted using the drop command:
db.myColl.drop()
This will delete it physically but the "virtual" one will still be there.
As for your example, running:
db.stat.insert({}); print("Collection stat exists:" + (db.getCollectionNames().indexOf("stat") !== -1));
will tell you:
Collection stat exists: true

Related

Is it possible to run a "dummy" query to see how many documents _would_ be inserted

I am using MongoDB to track unique views of a resource.
Everytime a user views a specific resource for the first time, a new view is logged in the db.
If that same user views the same resource again, the unique compound index on the collection blocks the insert of the duplicate.
For bulk inserts, with { ordered: false }, Mongo allows the new views through and blocks the duplicates. The return value of the insert is an object with an insertedCount property, telling me how many docs made it past the unique index.
In some cases, I want to know how many docs would be inserted before running the query. Then, based on the dummy insertedCount, I would choose to run the query, or not.
Is there a way to test a query and have it do everything except actually inserting the docs?
I could solve this by running some js serverside to get the answer I need. But I would prefer to let the db do those checks

Why the result of db.user.count() is 0 in mongo?

as you can see in the image below I just create an user even though it still gave 0 , and the same thing with collections when I run show collection it shows me one , but when when I do db.collection.count() gave me 0.
the image for db.collection.count()
I do have one document on this collection here is image from Mongo compass
As you can see there is no "user" collection in this database , there is only one collection and its name is "Databases_for_tp" so counting documents in not existing collection will show always 0.
You misenterpreted the meaniing of count() command , it counts how many documents there is in single collection , not how many collections there is in chosen database.
You can find the users when you create them in the admin database even they are created to authenticate in different database.
check:
use admin
show collections
db.system.users.count()
Note also it is a good practice to add code as text and not as pictures so it is easier to interpret.

MongoDB Error Code 16755 - Can't extract geo keys & duplicate vertices

When I try to create an index on geometry db.polygons.createIndex({"geometry":"2dsphere"}), it stops at a certain polygon with the error code 16755. It says it Can't extract geo keys and Duplicate vertices: 18 and 20.
So upon further inspection, it seems like this happens when 2 nodes in a polygon are close together, or even duplicates.
I then go manually remove this node in QGIS and re-try the process, only to find there's another polygon with the same issue.
How can I fix this issue without having to repeat the entire process of fixing polygon > uploading to MongoDB > creating index? Is there a way I can find out how many polygons have this issue?
I hit a similar problem. I just needed to find the valid records in my dataset (I discarded the records with Duplicate Vertices).
I renamed the collection -
db.myCollection.renameCollection('myCollectionBk')
Then I added a single record from the original collection into a new collection and added a geospatial index to the collection
db.myCollection.insert(db.myCollectionBk.findOne()) // recreate the collection
db.myCollection.createIndex({geometry:"2dsphere"}) // create the index (assumes the geometry on the record is valid)
db.myCollection.remove({}) // remove the record
Then I added the valid records into the new collection.
db.myCollectionBk.find().forEach(function(x){
db.myCollection.insert(x);
})
Invalid records are simply ignored.
In your case you probably want to get the WriteResult from your insert, and look to see if it was successful. Something like
var errors = []
db.myCollectionBk.find().forEach(function(x){
var result = db.myCollection.insert(x);
if (result.writeError) {
errors.push({x._id:result.writeError.errmsg});
}
})
As another alternative, check out this question (I couldn't get this to work)
So what I did was, I first created the collection with the index and then tried inserting using mongoimport which gave me how many were inserted successfully.
> db.someNewCollection.createIndex({"geometry":"2dsphere"})
To insert GeoJSON into MongoDB I did the following:
$ jq --compact-output ".features" yourGeoJSON > output.geojson
$ mongoimport --db someDB -c someNewCollection --file "output.geojson" --jsonArray

Insert all documents from one collection into another collection in MongoDB database

I have a python script that collects data everyday and inserts it into a MongoDB collection (~10M documents). Sometimes the job fails and I am left with partial data which is not useful to me. I would like to insert the data into a staging collection first and then copy or move all documents from the staging collection into the final collection only when the job finishes and the data is complete. I cannot seem to find a straight forward solution for doing this as a "bulk" type operation, but it seems there should be one.
In SQL it would be something like this:
INSERT INTO final_table
SELECT *
FROM staging_table
I thought that db.collection.copyTo() would work for this but it seems it makes the destination collection a clone of the source collection.
Additionally, I know from this: mongodb move documents from one collection to another collection that I can do something like the following:
var documentsToMove = db.collectionA.find({});
documentsToMove.forEach(function(doc) {
db.collectionB.insert(doc);
}
But it seems like there should be a more efficient way.
So, How can I take all documents from one collection and insert them into another collection in the most efficient manner?
NOTE: the final collection has data in it already. The new documents that I want to move over would be adding to this data, e.g if my staging collection has 2 documents and my final collection has 10 documents, I would have 12 documents in my final collection after I move the staging data over.
You can use db.cloneCollection(); see mondb cloneCollection
if you no longer need the staging collection you can simply use the renaming option.
switch to admin db
db.runCommand({renameCollection:"staging.CollectionA",to:"targetdb.CollectionB"})

is there any way to restore predefined schema to mongoDB?

I'm beginner with mongoDB. i want to know is there any way to load predefined schema to mongoDB? ( for example like cassandra that use .cql file for this purpose)
If there is, please intruduce some document about structure of that file and way for restoring.
If there is not, how i can create an index only one time when I create a collection. I think it is wrong if i create index every time I call insert method or run my program.
p.s: I have a multi-threaded program that every thread insert and update my mongo collection. I want to create index only one time.
Thanks.
To create an index on a collection you need to use ensureIndex command. You need to only call it once to create an index on a collection.
If you call ensureIndex repeatedly with the same arguments, only the first call will create an index, all subsequent calls will have no effect.
So if you know what indexes you're going to use for your database, you can create a script that will call that command.
An example insert_index.js file that creates 2 indexes for collA and collB collections:
db.collA.ensureIndex({ a : 1});
db.collB.ensureIndex({ b : -1});
You can call it from a shell like this:
mongo --quiet localhost/dbName insert_index.js
This will create those indexes on a database named dbName on your localhost. It's worth noticing that if your database and/or collections are not yet created, this will create both the database and the collections for which you're adding the indexes.
Edit
To clarify a little bit. MongoDB is schemaless so you can't restore it's schema.
You can only create indexes and collections (by using createCollection helper).
MongoDB is basically schemaless so there is no definition of a schema or namespaces to be restored.
In the case of indexes, these can be created at any time. There does not need to be a collection present or even the required fields for the index as this will all be sorted out as the collections are created and when documents are inserted that matches the defined fields.
Commands to create an index are generally the same with each implementation language, for example:
db.collection.ensureIndex({ a: 1, b: -1 })
Will define the index on the target collection in the target database that will reference field "a" and field "b", the latter in descending order. This will happen even if the collection or even the database does not exist as yet, or in fact will establish a blank namespace in that case.
Subsequent calls to the same index creation method do not actually re-create the index. Where the same index is specified to one that already exists it is effectively skipped as a "no-operation".
As such, you can simply feed all your required index creation statements at application startup and anything that is not already present will be created. Anything that already exists will be left alone.