Sails.js Waterline native MongoDB query by ID? - mongodb

I am trying to use the Waterline .native() method to query an item by id in the database. This is what my code looks like:
// Consutruct the query based on type
var query = {};
if (req.param('type') === 'id') {
query = { _id: req.param('number') };
} else {
query = { 'data.confirmationNumber': req.param('number') };
}
Confirmations.native(function(error, collection) {
if (error) {
ResponseService.send(res, 'error', 500, 'Database error.');
} else {
collection.find(query).toArray(function(queryError, queryRecord) {
if (queryError) {
ResponseService.send(res, 'error', 500, 'Database error.');
} else {
if (queryRecord.length > 0) {
ResponseService.send(res, 'success', 200, queryRecord[0]);
} else {
ResponseService.send(res, 'error', 404, 'Your confirmation details could not be found.');
}
}
});
}
});
When the query is 'data.confirmationNumber' it works but if it is '_id' it dows not work. How do I fix this?

if your Id is a ObjectId see this
var ObjectId = require('mongodb').ObjectID;
{_id: new ObjectId(req.param('number') )}

Iniside Model and in attribute define the id field like this
id : {type : 'objectid',primaryKey:true}
When you are querying the code
Here my model name is - QuizModel and the id is coming in the params quizId so here quizId is equal to the _id in the mongodb database
QuizModel.find({_id: QuizModel.mongo.objectId(quizId)})
.then(function(response){
})
.catch(function(error){
});

Related

MongoDB and triggers

I have a post call that inserts records in an Atlas mongodb database, the Atlas service has a trigger active to increment a correlative field (no_hc), then I make a query to retrieve that correlative field with the _id generated in the insert of the document. I put the code below so that they can tell me what I am doing wrong since this code sometimes returns null the field no_hc. Thanks since now
I add information about what I need to execute. I have a collection on which every time a document is added the mongodb server executes a trigger to increment a certain field, the problem is that the findoneandupsert query returns the inserted document with the autoincrement field set to null, since apparently the trigger is executed after the result of findoneandupsert is returned, how can I solve this issue?
router.post('/admisionUpsert', (req, res) => {
admisionUpsert(req.body)
.then(data => res.json(data))
.catch(err => res.status(400).json({ error: err + ' Unable to add ' }));
})
async function admisionUpsert(body) {
let nohc = body.no_hc
delete body['no_hc'];
let id;
let noprot
await Paciente.findOneAndUpdate(
{ no_hc: nohc },
{
apellido: body.apellido,
nombre: body.nombre,
sexo: body.sexo,
no_doc: body.no_doc,
fec_nac: body.fec_nac,
calle: body.calle,
no_tel: body.no_tel,
email: body.email
}, {
new: true,
upsert: true
}
)
.then(data => { id = data._id })
console.log("id pac", id)
Paciente.findOne({ _id: id }).then(data => { nohc = data.no_hc })
console.log("nohc pac", nohc)
await Protocolo.findOneAndUpdate(
{ no_prot: "" },
{
cod_os: body.cod_os,
no_os: body.no_os,
plan_os: body.plan_os,
no_hc: nohc,
sexo: body.sexo,
medico: body.medico,
diag: body.diag,
fec_prot: body.fec_prot,
medicacion: body.medicacion,
demora: body.demora
}, {
new: true,
upsert: true
}
)
.then(data => { id = data._id })
console.log("id prot", id)
Protocolo.findOne({ _id: id }).then(data => { noprot = data.no_prot })
console.log("noprot prot", noprot)
let practicasProtocolo = []
body.practicas_solicitadas.map((practica, index1) => {
practicasProtocolo.push({
no_prot: noprot,
cod_ana: practica.codigo,
cod_os: practica.cod_os,
estado_administrativo: practica.estado_administrtivo,
estado_muestra: practica.estado_muestra,
estado_proceso: practica.estado_proceso,
})
practica.parametro.map((parametro, index) => {
par = parametro.codigo
tipo_dato = parametro.tipo_dato
if ((tipo_dato === "numerico") || (tipo_dato === "frase") || (tipo_dato === "codigo")) {
practicasProtocolo[index1][par] = null;
}
})
})
console.log(practicasProtocolo)
practicasProtocolo.map(async (practica, index) => {
await new Practica(practica).save()
})
return { nohc: nohc, noprot: noprot }
}

feathers-mongodb Service.find({query: {_id}}) returns null

I have the schemas below:
students.graphql.schema.js
export default [
`
type StudentsWithPagination {
total: Int
items: [Students]
}
type Students {
_id: String!
name: String
address: Addresses
}
`,
];
addresses.graphql.schema.js
export default [
`
type AddressesWithPagination {
total: Int
items: [Addresses]
}
type Addresses {
_id: String!
title: String
}
`,
];
I have created two services by running feathers generate service students.service.js and addresses.services.js.
When I search addresses by title, I get result. However, when I search by _id, I get null. Something like:
const studentsResolvers = {
Students: {
address: student => {
const query = {
_id: student.address
}
return Addresses.find({ query }).then(result => {
console.log(result)
})
}
}
}
The code above produces null though student.address returns the right address._id. I still get null even I hardcode student.address with the right address._id
The code above will return null unless I search by address title. Something like:
const query = {
title: 'my-location'
}
_id is of type String, not ObjectID.
What am I doing wrong?
As documented in the feathers-mongodb adapter, since MongoDB itself (unlike Mongoose) does not have a schema, all query parameters have to be converted to the type in the database in a hook manually. The example can be adapted accordingly for $in queries:
const ObjectID = require('mongodb').ObjectID;
app.service('users').hooks({
before: {
find(context) {
const { query = {} } = context.params;
if(query._id) {
query._id = new ObjectID(query._id);
}
if(query.age !== undefined) {
query.age = parseInt(query.age, 10);
}
context.params.query = query;
return Promise.resolve(context);
}
}
});

Mongoose cannot findOne({_id : id}) with copied documents

I copied documents from a local database to my production database and when I try to get the document by Id by running model.findOne({_id : id}) and mongoose returns nothing. I am copying the documents over with the same Id, but I also tried with a new Id. I can find the document in the database and confirm that the JSON is correct, the Id is correct, etc and it won't find it. The documents I did not copy and where generated via my app still query fine with the findOne command. So, I have no idea what's going on
any help is greatly appreciated, thanks
groups.crud
getGroupById(id: string) {
logger.debug(".getGroupById id: " + id);
return new Promise(function(resolve, reject) {
GroupsModel.findById(id)
.populate('createdBy')
.then(function (group) {
logger.debug(".getGroupById");
if(group.createdBy.privacySettings.useUserName) {
group.createdBy.firstName = '';
group.createdBy.lastName = '';
}
resolve(group);
})
.catch(function(error) {
reject(error);
});
});
}
groups.routes
getGroupById(req, res, next) {
logger.debug('.getGroupById: BEG');
let id = req.params.id;
return groupsCrud.getGroupById(id)
.then(function(group) {
if(group) {
logger.debug('.getGroupById: get by id success');
let response = {
data : group
}
logger.debug('.getGroupById: response: ' + response);
res.json(response);
}
else {
logger.debug('.getGroupById: get by id failed 1');
res.status(404).json({ status : 404, message : "Group not found."});
}
})
.catch(function(error) {
logger.debug('.getGroupById: get by id failed 2 err = ' + JSON.stringify(error, null, 2));
res.sendStatus(404);
});
}

How to replace a manual id with an ObjectID _id in mongoDB?

Let's say I have a database with two collections, kids and classes. Each kid belongs to one class.
Each class has a previously created integer id.
I want to replace the kid.class_id with the (ObjectID) _id of the class, not the (integer) id of the class.
However, when I run the script below, it doesn't reset the class_id with the class._id -- it remains the old integer id.
mongoose.connect(someMongodbUri, { useMongoClient: true }, (err, db) => {
let kidsCount = 0;
db.collection('kids').find({}).each((err, kid) => {
kidsCount++;
db.collection('classes')
.findOne({ id: kid.class_id })
.then((class, err) => {
let newClassId = class._id;
db.collection('kids').updateOne(
{ _id: kid._id },
{ $set: { class_id: newClassId } }
).then(() => {
console.info('Updated', kid.class_id);
kidsCount--;
if (kidsCount === 0) { db.close(); }
});
});
});
});
Am I missing something? Thanks for any help you can offer!
We can convert integerId to Object id.
var ObjectId = require('mongodb').ObjectID;
let newClassId = ObjectId(class._id);
There may be better or elegent ways that i don't know, but this works for me.

Reading mongo collection created outside of meteor

I have a mongo collection that is created outside of Meteor that holds user info of people who want access to my app. It looks like this in MongoVue-
**tmpUsers**
/* 5 */
{
"_id" : ObjectId("54c7ae456587e23335915948"),
"email" : "trial#domain.com",
"first" : "Trial User",
"type" : "trial",
"active" : "Yes"
}
When I try to read this I get basically an empty collection structured like this -
collection:
d_docs: d._IdMap_..........
Here's my code -
**client**
var type = "";
var tmpCursor = tmpUsers.find({"email": Meteor.user().emails[0].address});
tmpCursor.forEach(function(rec) {
type = rec.type
});
Meteor.call("updateProfile", Meteor.userId(), type);
**server**
Meteor.methods({
"updateProfile": function(id, value){
Meteor.users.update({"_id": id}, {$set: {"profile.acctType": value}});
}
})
How would I update the client side code to read the type from tmpUsers?
Update:
Here is where I insert the record from outside of Meteor -
try {
$mongoDb = $mongoConn->abcdefg;
$collection = $mongoDb->tmpUsers;
$userInfo = array("email" => $_POST['email'], 'first' => $first,"type" => $_POST['type'], 'active' => $activation);
$collection->insert($userInfo);
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
Try with this.
Tracker.autorun(function(){
Meteor.subscribe('tmpUsers',function(){
var finde = tmpUsers.find({email:Meteor.user().emails[0].address}).count();
if (finde === 1){
console.log("found email");
} else{
console.log("not email found")
}
});
});