How to define object in array in Mongoose schema correctly with 2d geo index
You can declare trk by the following ways : -either
trk : [{ lat : String, lng : String }]
or
trk : { type : Array , "default" : [] }
In the second case during insertion make the object and push it into the array like
db.update({'Searching criteria goes here'},{ $push : { trk : { "lat": 50.3293714, "lng": 6.9389939 } //inserted data is the object to be inserted }});
or you can set the Array of object by
db.update ({'seraching criteria goes here ' },{ $set : { trk : [ { "lat": 50.3293714, "lng": 6.9389939 }, { "lat": 50.3293284, "lng": 6.9389634 } ]//'inserted Array containing the list of object' }});
I had a similar issue with mongoose :
fields: [ '[object Object]', '[object Object]', '[object Object]', '[object Object]' ] }
In fact, I was using "type" as a property name in my schema :
fields: [ { name: String, type: { type: String }, registrationEnabled: Boolean, checkinEnabled: Boolean } ]
To avoid that behavior, you have to change the parameter to :
fields: [ { name: String, type: { type: { type: String } }, registrationEnabled: Boolean, checkinEnabled: Boolean } ]
The problem I need to solve is to store contracts containing a few fields (address, book, num_of_days, borrower_addr, blk_data), blk_data is a transaction list (block number and transaction address).This question and answer helped me. I would like to share my code as below. Hope this helps.
- Schema definition. See blk_data.
var ContractSchema = new Schema( { address: {type: String, required: true, max: 100}, //contract address // book_id: {type: String, required: true, max: 100}, //book id in the book collection book: { type: Schema.ObjectId, ref: 'clc_books', required: true }, // Reference to the associated book. num_of_days: {type: Number, required: true, min: 1}, borrower_addr: {type: String, required: true, max: 100}, // status: {type: String, enum: ['available', 'Created', 'Locked', 'Inactive'], default:'Created'}, blk_data: [{ tx_addr: {type: String, max: 100}, // to do: change to a list block_number: {type: String, max: 100}, // to do: change to a list }] });
- Create a record for the collection in the MongoDB. See blk_data.
// Post submit a smart contract proposal to borrowing a specific book.exports.ctr_contract_propose_post = [ // Validate fields body('book_id', 'book_id must not be empty.').isLength({ min: 1 }).trim(), body('req_addr', 'req_addr must not be empty.').isLength({ min: 1 }).trim(), body('new_contract_addr', 'contract_addr must not be empty.').isLength({ min: 1 }).trim(), body('tx_addr', 'tx_addr must not be empty.').isLength({ min: 1 }).trim(), body('block_number', 'block_number must not be empty.').isLength({ min: 1 }).trim(), body('num_of_days', 'num_of_days must not be empty.').isLength({ min: 1 }).trim(), // Sanitize fields. sanitizeBody('*').escape(), // Process request after validation and sanitization. (req, res, next) => { // Extract the validation errors from a request. const errors = validationResult(req); if (!errors.isEmpty()) { // There are errors. Render form again with sanitized values/error messages. res.status(400).send({ errors: errors.array() }); return; } // Create a Book object with escaped/trimmed data and old id. var book_fields = { _id: req.body.book_id, // This is required, or a new ID will be assigned! cur_contract: req.body.new_contract_addr, status: 'await_approval' }; async.parallel({ //call the function get book model books: function(callback) { Book.findByIdAndUpdate(req.body.book_id, book_fields, {}).exec(callback); }, }, function(error, results) { if (error) { res.status(400).send({ errors: errors.array() }); return; } if (results.books.isNew) { // res.render('pg_error', { // title: 'Proposing a smart contract to borrow the book', // c: errors.array() // }); res.status(400).send({ errors: errors.array() }); return; } var contract = new Contract( { address: req.body.new_contract_addr, book: req.body.book_id, num_of_days: req.body.num_of_days, borrower_addr: req.body.req_addr }); var blk_data = { tx_addr: req.body.tx_addr, block_number: req.body.block_number }; contract.blk_data.push(blk_data); // Data from form is valid. Save book. contract.save(function (err) { if (err) { return next(err); } // Successful - redirect to new book record. resObj = { "res": contract.url }; res.status(200).send(JSON.stringify(resObj)); // res.redirect(); }); }); },];
- Update a record. See blk_data.
// Post lender accept borrow proposal.exports.ctr_contract_propose_accept_post = [ // Validate fields body('book_id', 'book_id must not be empty.').isLength({ min: 1 }).trim(), body('contract_id', 'book_id must not be empty.').isLength({ min: 1 }).trim(), body('tx_addr', 'tx_addr must not be empty.').isLength({ min: 1 }).trim(), body('block_number', 'block_number must not be empty.').isLength({ min: 1 }).trim(), // Sanitize fields. sanitizeBody('*').escape(), // Process request after validation and sanitization. (req, res, next) => { // Extract the validation errors from a request. const errors = validationResult(req); if (!errors.isEmpty()) { // There are errors. Render form again with sanitized values/error messages. res.status(400).send({ errors: errors.array() }); return; } // Create a Book object with escaped/trimmed data var book_fields = { _id: req.body.book_id, // This is required, or a new ID will be assigned! status: 'on_loan' }; // Create a contract object with escaped/trimmed data var contract_fields = { $push: { blk_data: { tx_addr: req.body.tx_addr, block_number: req.body.block_number } } }; async.parallel({ //call the function get book model book: function(callback) { Book.findByIdAndUpdate(req.body.book_id, book_fields, {}).exec(callback); }, contract: function(callback) { Contract.findByIdAndUpdate(req.body.contract_id, contract_fields, {}).exec(callback); }, }, function(error, results) { if (error) { res.status(400).send({ errors: errors.array() }); return; } if ((results.book.isNew) || (results.contract.isNew)) { res.status(400).send({ errors: errors.array() }); return; } var resObj = { "res": results.contract.url }; res.status(200).send(JSON.stringify(resObj)); }); },];