When I use mongoose.connection, models are connected directly with the unique connection.
In this case db1 is only used for querying (not model require). But db2 use 2 models.
How can I connect those models with db2 only?
Thanks for helping
const db1 = mongoose.createConnection("atlasuri").asPromise()
const db2 = mongoose.createConnection("localuri").asPromise()
app.get("/",async(req,res)=>{
const finded = (await db1).collection("users")
await finded.forEach(el=> console.log(el))
res.json(finded)
})
Models
const Criterion1=new mongoose.model('Criterion',new mongoose.Schema({
name:string
}));
const User=new mongoose.model('Criterion',new mongoose.Schema({
name:string
}));
Use createConnection():
const CriterionModel = require('./criterion');
const mongoose = require('mongoose');
const atlasuri = 'mongodb://localhost:27017/so1'; // <== your Atlas URI HERE
const localuri = 'mongodb://localhost:27017/so2';
const conn = mongoose.createConnection(atlasuri);
const conn2 = mongoose.createConnection(localuri);
const Criterion1 = conn.model('Criterion', new mongoose.Schema({
name:String
}));
const users = conn2.model('Criterion', new mongoose.Schema({
name:String
}));
// atlasuri
conn.on('connected', async () => {
const doc = await Criterion1({ // add a document
'name': 'Only in atlasuri'
});
await doc.save((err, doc) => {
if (err) {
console.log('error adding!');
}
});
console.log('Added to atlas');
});
// localuri
conn2.on('connected', async () => {
// add a document
const doc = await users({ // add a document
'name': 'Only in localuri'
});
doc.save((err, doc) => {
if (err) {
console.log('error adding!');
}
});
console.log('Added to local');
});
function handleExit(signal) {
console.log(`Received ${signal}. Shutting down.`);
conn.close();
conn2.close();
process.exit(0);
}
process.on('SIGINT', handleExit);
process.on('SIGQUIT', handleExit);
process.on('SIGTERM', handleExit);
In criterion.js:
const mongoose = require('mongoose');
const CriterionSchema = mongoose.Schema({
name:String
});
module.exports = mongoose.model('Criterion', CriterionSchema);
Related
I am new to using Graphql and MongoDB. I am trying to insert data from an existing javascript file where the data has been defined. I was trying to use a mutation in order to achieve this but I have no clue what I'm really doing. Any help would be nice.
const dotenv = require('dotenv');
dotenv.config();
const { ApolloServer, gql } = require('apollo-server');
const { MongoClient } = require('mongodb');
const items = require('./itemsListData');
const typeDefs = gql`
type Query {
items:[Item!]!
}
type Item{
id:ID!,
name:String!,
aisle:String!,
bay:String!,
price:Float!,
xVal:Int!,
yVal:Int!
}
type Mutation {
createItem(name: String!, aisle: String!): Item!
}
`;
console.log(items)
const resolvers = {
Query: {
items:() => items,
},
Item:{
id: ( { _id, id }) => _id || id,
},
Mutation: {
createItem: async(_, { name }, { db }) => {
// name:String!, bays:[Bay!]!, xStartVal:Int!, xEndVal:Int!, yStartVal:Int!, yEndVal:Int!
const newItem = {
items
}
// insert Item object into database
const result = await db.collection('Items').insert(newItem);
console.log("This is the result " + result);
return result.ops[0]; // first item in array is the item we just added
}
}
};
const start = async () => {
const client = new MongoClient("mongodb+srv://admin:admin#quickkartcluster.o0bsfej.mongodb.net/test", { useNewUrlParser: true, useUnifiedTopology: true });
await client.connect();
const db = client.db("QuickKart");
const context = {
db,
}
const server = new ApolloServer({
typeDefs,
resolvers,
context,
introspection: true
});
// The `listen` method launches a web server.
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
}
start();
here is my javascript data file
https://pastebin.com/wvGANBgR
I'm currently working on a MERN application with following/follower function for the users. I decided to create separate schemas for following and follower relationships detached from user schema.
Follower schema
const mongoose = require('mongoose');
const findOrCreate = require('mongoose-findorcreate');
const ObjectId = mongoose.Schema.Types.ObjectId;
const followerSchema = mongoose.Schema({
userId: {
type: ObjectId,
ref: 'User'
},
follower: {
type: [ObjectId],
ref: 'User'
}
});
followerSchema.plugin(findOrCreate);
const Follower = mongoose.model('Follower', followerSchema);
module.exports = { followerSchema, Follower };
Following schema
const mongoose = require('mongoose');
const findOrCreate = require('mongoose-findorcreate');
const ObjectId = mongoose.Schema.Types.ObjectId;
const followingSchema = mongoose.Schema({
userId: {
type: ObjectId,
ref: 'User'
},
following: {
type: [ObjectId],
ref: 'User'
}
});
followingSchema.plugin(findOrCreate);
const Following = mongoose.model('Following', followingSchema);
module.exports = { followingSchema, Following };
The problem however starts in my service where followings are created as supposed to. However, for followers mongoose create 6-8 documents at once with userIds that don't even exist in my db.
Here's the code of the followerService (it's the first function)
const { Follower } = require('../models/followerModel');
const { Following } = require('../models/followingModel');
const { User } = require('../models/userModel');
const mongoose = require('mongoose');
exports.changeFollowStatus = async (user, userId) => {
console.log({ userId: userId, user: user._id });
const newFollowing = await Following.findOrCreate({ userId: user._id }, (err, following, created) => {
console.log({following: following});
if (!err && !isFollowing(following, userId)) {
following.following.push(mongoose.Types.ObjectId(userId));
following.save();
User.findByIdAndUpdate(mongoose.Types.ObjectId(userId), {$inc: {follower: 1}});
} else {
const followingIndex = following.following.indexOf(mongoose.Types.ObjectId(userId));
following.following.splice(followingIndex, 1);
following.save();
User.findByIdAndUpdate(mongoose.Types.ObjectId(userId), { $inc: { follower: -1 } });
}
});
const newFollower = await Follower.findOrCreate({ userId: mongoose.Types.ObjectId(userId) }, (err, follower, created) => {
console.log({follower: follower});
if (!err && !isFollower(follower, user._id)) {
follower.follower.push(user._id);
follower.save();
User.findByIdAndUpdate(user._id, { $inc: { following: 1 } });
} else {
const followerIndex = follower.follower.indexOf(user._id);
follower.follower.splice(followerIndex, 1);
follower.save();
User.findByIdAndUpdate(user._id, { $inc: { following: -1 } });
}
});
};
exports.showFollowings = async (userId) => {
const followings = await Following.findOrCreate({ userId: mongoose.Types.ObjectId(userId) });
return followings.following;
};
exports.showFollowers = async (userId) => {
const followers = await Follower.findOrCreate({ userId: mongoose.Types.ObjectId(userId) });
return followers.follower;
};
const isFollowing = (newFollowing, userId) => {
return newFollowing.following.includes(mongoose.Types.ObjectId(userId));
};
const isFollower = (newFollower, userId) => {
return newFollower.follower.includes(userId);
}
Now, my following adding code and follower adding code look almost identical, but for some reason for followers, mongoose creates many more documents. The strange thing is that there is a follower document with the correct userId, but many other with random userIds get created which doesn't happen with followings which works as supposed to.
I also checked whether I pass the correct values and everything seems to be fine. But just for reference, here's the controller function from which I pass the values.
exports.changeFollowingStatus = async (req, res, next) => {
passport.authenticate('jwt', async (err, user, info) => {
if (err) {
console.error({ authError: err });
};
if (info !== undefined) {
console.error({ authError: info.message });
res.status(403).send(info.message);
} else {
console.log({params: req.params});
const userToFollow = req.params.id;
await FollowerService.changeFollowStatus(user, userToFollow);
res.status(200).send({ message: 'success' })
}
})(req, res, next);
};
Could anyone help me with this bug or at least navigate me towards the right direction? I can't seem to find solution to my problem. Thank you all in advance!
I have a file CreateNewUserID.js, which has the code as below.
const Connection = require('./database/Connection')
const createNewUserID = async(connData, userId) => {
try{
var getConn = await Connection.get().getConn();
const query = `exec BaseDB.get_client_info`
var clientusers = await getConn.query(query);
var getConn1 = await Connection.get().getConnection(connData)
var res = await getConn1.execute('BaseDB.get_all_existing_users');
res.recordsets[1].map(async (val) => {
try{
var newid = val.id+'NEWID';
var getConn2 = await Connection.get().getConnection(connData)
getConn2.input('userid', userid)
getConn2.input('updatedid', newid)
var res2 = await getConn2.execute(`BaseDB.update_users_with_newid`)
} catch (err) {
console.log(err)
return { err, message: 'First DB Connection' }
}
})
} catch (err) {
console.log(err)
return { err, message: 'Second DB Connection' }
}
}
const connData = {
"clientuserid": "12345"
}
createNewUserID(connData)
Also I have a Connection.js where I have made DB connection configurations of Base Database and client DB.The client DB Database will be dynamic. So, for now I am passing the DB name through constant connData. I have defined connData in the same file above in CreateNewUserID.js.
My Connection.js is below:
const sql = require('mssql')
class Connection {
// CONNECTION CONFIGURATION OF CLIENT DB
getConnection = async (conData) => {
const connData = JSON.parse(conData)
try {
// sql.close();
const config = {
user: process.env.SQL_USER,
password: process.env.SQL_PASSWORD,
server: process.env.SQL_SERVER,
database: connData.clientuserid
}
const pool = await new sql.ConnectionPool(config)
const req=await pool.connect()
const conn = await req.request()
// const req = await sql.connect(config)
// const conn = await req.request()
return conn;
} catch (err) {
return err;
}
};
// CONNECTION CONFIGURATION OF BASE DB
getConn = async () => {
try {
// sql.close();
const config = {
user: process.env.SQL_USER,
password: process.env.SQL_PASSWORD,
server: process.env.SQL_SERVER,
database: process.env.SQL_DATABASE
}
const pool = await new sql.ConnectionPool(config)
const req=await pool.connect()
const conn = await req.request()
// const req = await sql.connect(config)
// const conn = await req.request()
return conn;
} catch (err) {
return err;
}
};
}
Connection.__instance = null;
Connection.get = () => {
if (!Connection.__instance) {
Connection.__instance = new Connection();
}
return Connection.__instance;
};
module.exports = Connection;
When I try to run the file through CMD with command node CreateNewUserID.js I am getting the error as unexpected token 0 in json at position 1 at first catch with message "First DB connection".
Why am I getting the error and how to resolve it. Please help. Thanks in advance
I am trying to find a specific document with mongoose in my Cosmosdb with this query described below.
const mongoose = require('mongoose');
var ObjectID = require('mongodb').ObjectID
const keys = require('../config/keys');
const Item = mongoose.model('items');
const uploadToBlob = async (containerName, blobName, json, id) => {
console.log('id', id)
Item.findOne({ _id: id }, (foundItem) => {
console.log(foundItem)
});
console.log('here')
Item.findOneAndDelete({ name: blobName });
};
I am successfully able to find the document when querying like this below.
const scanMongo = () => {
Item.find({
_id: {
$gt: ObjectID.createFromTime(Date.now() / keys.mongoPurgeInterval)
}}, (err, foundItems) => {
if(err) {
console.log("Oops", err);
return;
}
foundItems.forEach(item => {
JSON.stringify(item)
const blobName = item.name;
json = "'"+item+"'"
const id = item._id
uploadToBlob(keys.containerName, blobName, json, id);
});
});
}
This is what the object I'm looking for looks like when pulled from the query above.
[ { _id: 5cabd5c6e16288230cba2cf6, name: 'test', value: 1, __v: 0 } ]
For kicks, here my model.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const itemSchema = new Schema({
name: String,
value: Number,
});
mongoose.model('items', itemSchema);
I'm befuddled. Any help would be bawler. Thanks!!!
Yeah, the first parameter is supposed to catch the error.
Item.findOne({ _id: id }, (error, foundItem) => {
console.log(foundItem)
I'm trying to select a document by id
I've tried:
collection.update({ "_id": { "$oid": + theidID } }
collection.update({ "_id": theidID }
collection.update({ "_id.$oid": theidID }}
Also tried:
collection.update({ _id: new ObjectID(theidID ) }
This gives me an error 500...
var mongo = require('mongodb')
var BSON = mongo.BSONPure;
var o_id = new BSON.ObjectID(theidID );
collection.update({ _id: o_id }
None of these work. How to select by _id?
var mongo = require('mongodb');
var o_id = new mongo.ObjectID(theidID);
collection.update({'_id': o_id});
This the approach that worked for me.
var ObjectId = require('mongodb').ObjectID;
var get_by_id = function(id, callback) {
console.log("find by: "+ id);
get_collection(function(collection) {
collection.findOne({"_id": new ObjectId(id)}, function(err, doc) {
callback(doc);
});
});
}
now you can just use this:
var ObjectID = require('mongodb').ObjectID;
var o_id = new ObjectID("yourObjectIdString");
....
collection.update({'_id': o_id});
You can see documentation here
With native_parser:false:
var BSON = require('mongodb').BSONPure;
var o_id = BSON.ObjectID.createFromHexString(theidID);
With native_parser:true:
var BSON = require('mongodb').BSONNative;
var o_id = BSON.ObjectID.createFromHexString(theidID);
I just used this code in Node.js app in controller file, and it works:
var ObjectId = require('mongodb').ObjectId;
...
User.findOne({_id:ObjectId("5abf2eaa1068113f1e")})
.exec(function(err,data){
// do stuff
})
do not forget to install "mongodb" before, and if you are using encryption of your passwords with bcrypt with "presave", be sure that you will not encrypt password after each modification of the record in DB.
/* get id */
const id = request.params.id; // string "5d88733be8e32529c8b21f11"
/* set object id */
const ObjectId = require('mongodb').ObjectID;
/* filter */
collection.update({
"_id": ObjectId(id)
} )
ObjectId reports deprecated when called inside find() function in "mongodb": "^4.1.2" if the ObjectId is imported like this
const ObjectId = require('mongodb').ObjectID;
instead, when I import it with named import there is no deprecated warning
const { MongoClient, ObjectId } = require("mongodb");
then I can call it regularly
const findResult = await collection.find({_id: ObjectId(id)}).toArray();
This is what worked for me.
Using mongoDB
const mongoDB = require('mongodb')
Then at the bottom where I am making my express get call.
router.get('/users/:id', (req, res) => {
const id = req.params.id;
var o_id = new mongoDB.ObjectID(id);
const usersCollection = database.collection('users');
usersCollection.findOne({
_id: o_id
})
.then(userFound => {
if (!userFound){
return res.status(404).end();
}
// console.log(json(userFound));
return res.status(200).json(userFound)
})
.catch(err => console.log(err));
});`
The answer depends upon the variable type you are passing in as the id. I pulled an object id by doing a query and storing my account_id as the ._id attribute. Using this method you simply query using the mongo id.
// begin account-manager.js
var MongoDB = require('mongodb').Db;
var dbPort = 27017;
var dbHost = '127.0.0.1';
var dbName = 'sample_db';
db = new MongoDB(dbName, new Server(dbHost, dbPort, {auto_reconnect: true}), {w: 1});
var accounts = db.collection('accounts');
exports.getAccountById = function(id, callback)
{
accounts.findOne({_id: id},
function(e, res) {
if (e) {
callback(e)
}
else {
callback(null, res)
}
});
}
// end account-manager.js
// my test file
var AM = require('../app/server/modules/account-manager');
it("should find an account by id", function(done) {
AM.getAllRecords(function(error, allRecords){
console.log(error,'error')
if(error === null) {
console.log(allRecords[0]._id)
// console.log('error is null',"record one id", allRecords[0]._id)
AM.getAccountById(
allRecords[0]._id,
function(e,response){
console.log(response,"response")
if(response) {
console.log("testing " + allRecords[0].name + " is equal to " + response.name)
expect(response.name).toEqual(allRecords[0].name);
done();
}
}
)
}
})
});
If you use Mongosee, you can simplify the function
FindById:
this replace in mongodb: "_id" : ObjectId("xyadsdd434434343"),
example:
// find adventure by id and execute
Adventure.findById('xyadsdd434434343', function (err, adventure) {});
https://mongoosejs.com/docs/api.html#model_Model.findById
I'm using client "mongodb": "^3.6.2" and server version 4.4.1
// where 1 is your document id
const document = await db.collection(collection).findOne({ _id: '1' })
console.log(document)
If you want to copy and paste here's all you need.
const { MongoClient } = require('mongodb')
const uri = '...'
const mongoDb = '...'
const options = {}
;(async () => {
const client = new MongoClient(uri, options)
await client.connect()
const db = client.db(mongoDb)
const document = await db.collection(collection).findOne({ _id: '1' })
console.log(document)
)}()
In Mongoose, the Model.findById() function is used to find one document by its _id. The findById() function takes in a single parameter, the document id. It returns a promise that resolves to the Mongoose document if MongoDB found a document with the given id, or null if no document was found.
const schema = new mongoose.Schema({ _id: Number }, { versionKey: false });
const Model = mongoose.model('MyModel', schema);
await Model.create({ _id: 1 });
// `{ _id: 1 }`
await Model.findById(1);
// `null` because no document was found
await Model.findById(2);
When you call findById(_id), Mongoose calls findOne({ _id }) under the hood. That means findById() triggers findOne() middleware.
const schema = new mongoose.Schema({ _id: Number }, { versionKey: false });
schema.pre('findOne', function() {
console.log('Called `findOne()`');
});
const Model = mongoose.model('MyModel', schema);
await Model.create({ _id: 1 });
// Prints "Called `findOne()`" because `findById()` calls `findOne()`
await Model.findById(1);
Mongoose casts queries to match your schema. That means if your _id is a MongoDB ObjectId, you can pass the _id as a string and Mongoose will convert it to an ObjectId for you.
const _id = '5d273f9ed58f5e7093b549b0';
const schema = new mongoose.Schema({ _id: mongoose.ObjectId }, { versionKey: false });
const Model = mongoose.model('MyModel', schema);
await Model.create({ _id: new mongoose.Types.ObjectId(_id) });
typeof _id; // 'string'
// `{ _id: '5d273f9ed58f5e7093b549b0' }`
const doc = await Model.findById(_id);
typeof doc._id; // 'object'
doc._id instanceof mongoose.Types.ObjectId; // true
Source