MongoDB search a key between collections - mongodb

I have a Mongo db with a lot of collection with only 1 document each, I want to search in each of this collection a specific key and and print its value, is possible with a query or need a Python script ?

Easy enough to do in python
from pymongo import MongoClient
db = MongoClient()['yourdatabase']
key_to_find = 'yourkey'
for collection in db.list_collection_names():
records = db[collection].find({key_to_find: { "$exists": True}})
for record in records:
print (record)

Related

mongodb: number of collections in database - native driver

I'm using the mongodb native driver v3.2.3 and trying to query how many collections are in the current database. I thought it would be
db.listCollections()
But this does not appear to return a count.
You can get the collection count of a database via the stats method:
let stats = await db.stats();
console.log(stats.collections);
That function returns a cursor which you can then use 'forEach()' on. Like this:
db.listCollections({}, {nameOnly: true}).forEach((_col) => {
console.log(_col.name)
})
You will then have to increment a counter for each collection, or push each collection name to an array and then check it's length.
Another way to get the collection count quickly would be to use the 'collections()' function like this:
db.collections({}, (error, collections) => {
console.log(collections.length)
})
listCollections source
collections source

Trouble with PyMongo with conditional update inside of find_and_modify() call

I am trying to do a conditional update to a nested value. basically one variable in a nested array of 2 variables per array item has a boolean component I want to update based on the string value of the other variable.
I also want to do all of that based on a targeted find query. I came up with this below, but it doesn't work.
#!/usr/bin/env python
import ssl
from pymongo import MongoClient
client = MongoClient("somehost", ssl=True, ssl_cert_reqs=ssl.CERT_NONE, replicaSet='rs0')
db = client.maestro
mycollection = db.users
print 'connected, now performing update'
mycollection.find_and_modify(query={'emailAddress':'somedude#someplace.wat'}, update={ "nested.name" : "issomename" }, { "$set": {'nested.$*.value': True}}, upsert=True, full_response=True)
This code results in:
SyntaxError: non-keyword arg after keyword arg
This makes me think that the find_and_modify() method can't handle the conditional update bit.
Is there some way to achieve this, or have I gone down a wrong path? What would you all suggest as a better approach?
#!/usr/bin/env python
import ssl
from pymongo import MongoClient
client = MongoClient("somehost.wat", ssl=True, ssl_cert_reqs=ssl.CERT_NONE, replicaSet='rs0')
db = client.dbname
mycollection = db.docs
user_email = 'user#somehost.wat'
mycollection.update({ "emailAddress": user_email,"nestedvalue": { "$elemMatch" : {"name": "somename"} } }, { "$set": {"nestedvalue.$.value": True}})
This did the trick.
Instead of find_any_modify, use update_one if you want to update just one record or update_many in case of many.
The usage is like this:
mycollection.upadte_one({'emailAddress':'somedude#someplace.wat'},{"$set": {'nested.$*.value': True}})
for further detail please go through this link:
https://docs.mongodb.com/getting-started/python/update/

Using findOne in mongodb to get element with max id

I am trying to retrieve one element from a mongo collection, the one with the greatest _id field. I know this can be done by querying:
db.collection.find().sort({_id: -1}).limit(1)
But it kind of seems unelegant and I was wondering whether there is a way to get that specific element using findOne()
Note: I want to do this because, from what I've read in ObjectId, the first bytes correspond to the miliseconds since the Epoch and thus, the last element being inserted will have the greatest _id. Is there any other way to retrieve the last element inserted in a collection?
You should use find, like you already are, and not aggregation which will be slower since it needs to scan all the values of _id fields to figure out the max.
As comments pointed out there is no difference between using find() and findOne() - functionally or elegance-wise. In fact, findOne in the shell (and in the drivers which implement it) is defined in terms of find (with limit -1 and with pretty print in the shell).
If you really want to do the equivalent of
db.collection.find().sort({_id:-1}).limit(1).pretty()
as findOne you can do it with this syntax:
db.collection.findOne({$query:{},$orderby:{_id:-1}})
You can get max _id using aggregation of mongodb. Find and sort may overkill's.
db.myCollection.aggregate({
$group: {
_id: '',
last: {
$max: "$_id"
}
}
});
with PHP driver (mongodb)
using findOne()
$filter=[];
$options = ['sort' => ['_id' => -1]]; // -1 is for DESC
$result = $collection->findOne(filter, $options);
$maxAge = $result['age']
import pymongo
tonystark = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = tonystark["tonystark_db"]
savings = mydb["customers"]
x = savings.find().sort("_id")
for s in x:
print(s)
$maxId="";
$Cursor =$collection->find();
foreach($cursor as $document) {
$maxid =max($arr=(array($document['id'])));
}
print_r($maxid+1);

mongo copy from one collection to another (on the same db)

I have got mongo db called test and in this db two collections collection1 and collection1_backup.
How to replace content of collection1 with data from collection1_backup.
The best way to have done this (considering the name of the collection ends with _backup) is possibly to have used mongorestore: http://docs.mongodb.org/manual/reference/mongorestore/
However in this case it depends. If the collection is unsharded you can use renameCollection ( http://docs.mongodb.org/manual/reference/command/renameCollection/ ) or you can use a more manual method of (in JavaScript code):
db.collection1.drop(); // Drop entire other collection
db.collection1_backup.find().forEach(function(doc){
db.collection1.insert(doc); // start to replace
});
Those are the most common methods of doing this.
This can be done using simple command:
db.collection1_backup.aggregate([ { $match: {} }, { $out: "collection1" } ])
This command will remove all the documents of collection1 and then make a clone of collection1_backup in collection1.
Generic Command would be
db.<SOURCE_COLLECTION>.aggregate([ { $match: {} }, { $out: "<TARGET_COLLECTION>" } ])
If TARGET_COLLECTION does not exist, the above command will create it.
also usefull:
to export collection to json file
mongoexport --collection collection1_backup --out collection1.json
to import collection from json file
mongoimport --db test --collection collection1 --file collection1.json
to import single collection from backup/dump file one need to convert *.bson file to *.json
by using
bsondump collection1_backup.bson > collection1_backup.json
simply just do this.
//drop collection1
db.collection1.drop();
//copy data from collection1_backup to collection1
db.collection1.insert(db.collection1_backup.find({},{_id:0}).toArray());
Using Java Driver
Try below one:
public void copyTo(String db,String sourceCollection,String destinationCollection,int limit) throws
UnknownHostException {
MongoClient mongo = new MongoClient("localhost", 27017);
DB database = mongo.getDB(db);
DBCollection collection = database.getCollection(sourceCollection);
DBCursor dbCursor = collection.find().limit(limit);
List<DBObject> list = dbCursor.toArray();
DBCollection destination = database.getCollection(destinationCollection);
destination.insert(list, WriteConcern.NORMAL); //WRITE CONCERN is based on your requirment.
}
Better way would be to use .toArray()
db.collection1.drop(); // Drop entire other collection
// creates an array which can be accessed from "data"
db.collection1_backup.find().toArray(function(err, data) {
// creates a collection and inserting the array at once
db.collection1.insert(data);
});
You can use a simple command to Backup MongoDB Collection. It will work only on MongoDB 4.0 or earlier versions.
db.sourceCollectionName.copyTo('targetCollectionName')
Your targetCollectionName must be in Single(') or Double(") Quote
Note:
The db.collection.copyTo() method uses the eval command internally. As
a result, the db.collection.copyTo() operation takes a global lock
that blocks all other read and write operations until the
db.collection.copyTo() completes.
Drop collection1
then use this query
var cursor = db.collection1_backup.find();
var data = [];
while(cursor.hasNest()){
data.push(cursor.next());
}
db.collection1.insertMany(data)

Finding all records containing a given subfield in mongodb

In mongodb, i can find all those records in a collection in database db that contain a particular field using the following query
var doc = db.collection_name.find({field_name:{$exists:true}})
Now consider the following document:
{
"somefield":"someval",
"metadata": {"id":"someval",
"client_url":"http://www.something.com"
}
}
What would be the query for getting all records having the id field in metadata ?
Please Help.
Thank You
You can use dot notation to reference sub-document fields
var doc = db.collection_name.find({"metadata.id":{$exists:true}})