[英]How to define object in array in Mongoose schema correctly with 2d geo index
我目前在為以下文檔創建架構時遇到問題。 來自服務器的響應總是將“trk”字段值返回為 [Object]。 不知何故,我不知道這應該如何工作,因為我至少嘗試了所有對我有意義的方法;-)
如果這有幫助,我的 Mongoose 版本是 3.6.20 和 MongoDB 2.4.7 在我忘記之前,最好也將其設置為 Index (2d)
原始數據:
{
"_id": ObjectId("51ec4ac3eb7f7c701b000000"),
"gpx": {
"metadata": {
"desc": "Nürburgring VLN-Variante",
"country": "de",
"isActive": true
},
"trk": [
{
"lat": 50.3299594,
"lng": 6.9393006
},
{
"lat": 50.3295046,
"lng": 6.9390688
},
{
"lat": 50.3293714,
"lng": 6.9389939
},
{
"lat": 50.3293284,
"lng": 6.9389634
}]
}
}
貓鼬模式:
var TrackSchema = Schema({
_id: Schema.ObjectId,
gpx: {
metadata: {
desc: String,
country: String,
isActive: Boolean
},
trk: [{lat:Number, lng:Number}]
}
}, { collection: "tracks" });
Chrome 中網絡選項卡的響應總是如下所示(這只是錯誤的 trk 部分):
{ trk:
[ [Object],
[Object],
[Object],
[Object],
[Object],
[Object],
我已經為“trk”嘗試了不同的模式定義:
希望你能幫我 ;-)
您可以通過以下方式聲明 trk : - 要么
trk : [{
lat : String,
lng : String
}]
或者
trk : { type : Array , "default" : [] }
在插入期間的第二種情況下,制作對象並將其推入數組中
db.update({'Searching criteria goes here'},
{
$push : {
trk : {
"lat": 50.3293714,
"lng": 6.9389939
} //inserted data is the object to be inserted
}
});
或者您可以設置對象數組
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'
}
});
我對 mongoose 有類似的問題:
fields:
[ '[object Object]',
'[object Object]',
'[object Object]',
'[object Object]' ] }
事實上,我在架構中使用“類型”作為屬性名稱:
fields: [
{
name: String,
type: {
type: String
},
registrationEnabled: Boolean,
checkinEnabled: Boolean
}
]
為避免這種行為,您必須將參數更改為:
fields: [
{
name: String,
type: {
type: { type: String }
},
registrationEnabled: Boolean,
checkinEnabled: Boolean
}
]
為了在模式中創建一個數組,我們必須再創建一個模式作為monetizationSchema
,它用於一次存儲一個數據,另一個作為blogSchema
,我們在方括號中包含monetizationSchema
作為數組的monetization
字段。
一次存儲一個數據的Schema
。
const monetizationSchema = new Schema({
amazonUrl: {
type: String,
required: true,
}
});
以數組形式monetization
的架構。
const blogSchema = {
monetization: [
monetizationSchema
],
image: {
type: String,
required: true
},
// ... etc
});
我需要解決的問題是存儲包含幾個字段(address、book、num_of_days、borrower_addr、blk_data)的合約,blk_data 是一個交易列表(區塊號和交易地址)。 這個問題和答案幫助了我。 我想分享我的代碼如下。 希望這可以幫助。
- 架構定義。 請參見 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
}]
}
);
- 在 MongoDB 中為集合創建一條記錄。 請參見 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();
});
});
},
];
- 更新記錄。 請參見 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));
});
},
];
感謝您的回復。
我嘗試了第一種方法,但沒有任何改變。 然后,我嘗試記錄結果。 我只是逐級向下鑽取,直到最終到達顯示數據的位置。
過了一會兒,我發現了問題:當我發送響應時,我通過.toString()
將其轉換為字符串。
我解決了這個問題,現在它工作得很好。 很抱歉誤報。
您可以如下聲明一個數組
trk : [{
lat : String,
lng : String
}]
但它會將[]
(空數組)設置為默認值。
如果你不想要這個默認值然后覆蓋這個默認值,你需要將默認值設置為undefined
如下
trk: {
type: [{
lat : String,
lng : String
}],
default: undefined
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.