MongoDB - Is it possible to compare documents through the _id field? - mongodb

As the title clearly describes, I need to make comparison between documents through the auto-generated _id field. For example, is it possible to make a query such as "newer/older records than the id 5e120e38c149d02d27ea750c" something like greater-than/less-than operations?
Something like the below one didn't do what it was expected:
num_apps = db.app.count_documents({"_id": {"$lt": "5e120e38c149d02d27ea750c"}})
p.s. Using the PyMongo module.

You can do that, but the problem with your query is you're passing a string as input but the type of _id in DB is ObjectId(), So input should match with it. So convert it before querying DB.
If using native mongodb driver :
const ObjectId = require('mongodb').ObjectID;
num_apps = db.app.count_documents({ "_id": { "$lt": ObjectId("5e120e38c149d02d27ea750c") } })
If using mongoose :
const mongoose = require('mongoose');
let id = mongoose.Types.ObjectId('5e120e38c149d02d27ea750c');
num_apps = db.app.count_documents({ "_id": { "$lt": id } })
If using pymongo :
from pymongo import MongoClient
from bson.objectid import ObjectId
num_apps = db.app.count_documents({ "_id": { "$lt": ObjectId("5e120e38c149d02d27ea750c") } })

Related

Is there a way to find collection Name from a field name in Mongo DB Query

I am new to Mongo DB and NoSQL world. I am trying to find an equivalent of dba_tab_cols of Oracle in Mongo DB. My intention is, if I know a field name, I should be able to find out what all collections have that field by a query. Is it even possible in Mongo DB?
For example, if you are looking for collections with the field name:
var collections = db.getCollectionNames()
var matches = []
for (let coll of collections) {
let result = db[coll].findOne({ name: { $exists: true }})
if (result) matches.push(coll)
}
printjson(matches)
Note that this will include where the field exists and also includes even if the value is null. So, if you want to exclude those collections with field value as null, use the following filter:
let result = db[coll].findOne({ name: { $exists: true, $ne: null }})
For fields which contains a substring of the value you are looking for, use Regex. For example, if you are looking for collections with field names containing name, and this would match for field names "firstName", "lastName" and "name".
let result = db[coll].aggregate([
{ $project: { flds: { "$objectToArray": "$$ROOT" }}},
{ $match: { "flds.k": /name/ }},
{ $limit: 1 }
]).hasNext()
NOTE:
This runs from mongo shell.
These scripts do not look for fields within nested objects and objects within arrays.
These look for collections within the current database only. For searching in all databases, you can try:
var dbNames = db.adminCommand({ listDatabases: 1, nameOnly: true })["databases"].map(d => d.name)
for (let dbname of dbNames) {
let collections = db.getSiblingDB(dbname).getCollectionNames()
// ...
}

Inserting more properties in MongoDB document

So I'm working on a comments, I'm inserting them into collection of existing posts and I want to have more than one comment in my Mongo document.
This is how I set one property in a single document:
let result = await db.collection('posts').update({
_id : mongo.ObjectId(id)},
{$set : {comment : req.body.newComment }})
So how to insert more of them in a particular document?
You can use push operator to do that.
let result = await db.collection('posts').update(
{ _id: mongo.ObjectId(id) },
{ $push: {comment: req.body.newComment} })
MongoDB Official Documentation for push operator

Aggregate and update with mongoose

I want to use the aggregate method to make my querys and modify my database by a value, I tried with $set but my database is not modified.
Here is how I do my query:
var filter = req.body.filter
var search = [ { $match: filter }, { $set: {item: "2"} }, { $sample: { size: 1 } }]
const result = await dataModel.aggregate(search)
I know there is also findOneAndUpdate but I would like to keep aggregate because I also want to use $project in my pipelines
thanks in advance !
You can use FindOneAndUpdate for change your db

Mongodb find array of ids

I have one array which has document ids.:
var ids = [ '5b3c7db4c079dc17dc75fc26', '5b3c7db4c079dc17dc75fc28' ]
I have one collection called Machines with documents inside.
I am trying to get documents from Machines collection using ids which are in my array.
Machines.find({ _id : { $in : ids } }).fetch();
this returns []
Try this:
var ids = [ ObjectId("5b3c7db4c079dc17dc75fc26"), ObjectId("5b3c7db4c079dc17dc75fc28") ]
Because Mongodb stores id as ObjectId("Actual Id")
Your
var ids = [ '5b3c7db4c079dc17dc75fc26', '5b3c7db4c079dc17dc75fc28' ]
looks like they're either hex string or native MongoDB BSON type ObjectID.
Try this for Meteor's Mongo:
import { Mongo } from 'meteor/mongo';
const ids = [
new Mongo.ObjectID('5b3c7db4c079dc17dc75fc26'),
new Mongo.ObjectID('5b3c7db4c079dc17dc75fc28'),
]
Machines.find({ _id : { $in : ids } }).fetch();
For better syntax, use .map() to get a new array of Mongo.ObjectID type IDs.
import { Mongo } from 'meteor/mongo';
const ids = ['5b3c7db4c079dc17dc75fc26', '5b3c7db4c079dc17dc75fc28', ...];
const mongoIds = ids.map(id => new Mongo.ObjectID(id));
Machines.find({ _id : { $in : mongoIds } }).fetch();
// if ids were ObjectIDs instead of literal strings
const objectIdToMongoIds = ids.map(id => new Mongo.ObjectID(id.toString()));
Machines.find({ _id: { $in: objectIdToMongoIds } });
meteor mongo es6 functional-programming
You can also try Machine.findById(req.params.id, () => {}

MongoDB update collection's data

I try to update an MongoDB data by using this code:
db.medicines.update({"_id":"586a048e34e5c12614a7424a"}, {$set: {amount:'3'}})
but unfortantly the query does not recognize the selector "_id":"586a048e34e5c12614a7424a", even if its exists.
Its succsed when I change the key to another like: name,rate and etc..
there is a special way to use update with _id parameter?
Thanks a head.
_id will be the unique ObjectId that mongodb generates for every document before inserting it. The query dint work because _id is an ObjectId and "586a048e34e5c12614a7424a" is a String. You need to wrap _id with ObjectId().
If you're using mongodb query
db.medicines.update({
"_id": ObjectId("586a048e34e5c12614a7424a")
}, {
$set: {
amount: '3'
}
});
If you are using mongoose. You can use findByIdAndUpdate
db.medicines.findByIdAndUpdate({
"_id": "586a048e34e5c12614a7424a"
}, {
$set: {
amount: '3'
}
});