Cách xác định đối tượng trong mảng trong lược đồ Mongoose một cách chính xác với chỉ mục địa lý 2d


113

Tôi hiện đang gặp sự cố khi tạo giản đồ cho tài liệu bên dưới. Phản hồi từ máy chủ luôn trả về các giá trị trường "trk" là [Đối tượng]. Bằng cách nào đó, tôi không biết điều này sẽ hoạt động như thế nào, vì tôi đã thử ít nhất tất cả các cách tiếp cận phù hợp với tôi ;-)

Nếu điều này hữu ích, phiên bản Mongoose của tôi là 3.6.20 và MongoDB 2.4.7 Và trước khi tôi quên, sẽ rất tuyệt nếu đặt nó là Chỉ mục (2d)

Dữ liệu gốc:

{
    "_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
    }]
    }
}

Lược đồ Mongoose:

var TrackSchema = Schema({
            _id: Schema.ObjectId,
            gpx: {
                metadata: {
                    desc: String,
                    country: String,
                    isActive: Boolean
                },
                trk: [{lat:Number, lng:Number}]
            }
        }, { collection: "tracks" });

Phản hồi từ tab Mạng trong Chrome luôn trông như thế này (đó chỉ là phần trk bị sai):

{ trk: 
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],

Tôi đã thử các định nghĩa Lược đồ khác nhau cho "trk":

  1. trk: Schema.Types.Mixed
  2. trk: [Schema.Types.Mixed]
  3. trk: [{type: [Number], index: "2d"}]

Hy vọng bạn có thể giúp tôi ;-)

Câu trả lời:


219

Bạn có thể khai báo trk bằng các cách sau: -

trk : [{
    lat : String,
    lng : String
     }]

hoặc là

trk : { type : Array , "default" : [] }

Trong trường hợp thứ hai trong quá trình chèn, hãy tạo đối tượng và đẩy nó vào mảng như

db.update({'Searching criteria goes here'},
{
 $push : {
    trk :  {
             "lat": 50.3293714,
             "lng": 6.9389939
           } //inserted data is the object to be inserted 
  }
});

hoặc bạn có thể đặt Mảng đối tượng bằng cách

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'
      }
});

bất kỳ ý tưởng nào về cách đặt tên các trường html trong trường hợp như vậy, tức là trong trường hợp chúng ta cần lưu trữ một mảng các đối tượng javascript trong cơ sở dữ liệu? Ví dụ: đặt tên các trường như trk.lattrk.lngtrong html sẽ không hoạt động.
Raeesaa

3
trk: {type: Array, "default": []} phù hợp nhất với tôi! Nó đơn giản và thanh lịch!
tuần trăng xoắn ốc

1
@DpGeek nếu bạn đang khai báo mảng ở định dạng đó, bạn không thể cập nhật trường mảng trực tiếp. Để cập nhật trực tiếp mảng, tôi đã sử dụng subchema {lat: String, lng: String}. Nếu bạn không muốn cơ sở đó thì trk: {type: Array, "default": []} sẽ là tốt nhất, nếu không bạn phải khai báo subchema.
Kundu

mặc định mà không có dấu ngoặc kép làm việc cho tôitrk : { type : Array , default : ['item1', 'item2'] }
Shardul

1
nó sẽ vẫn hoạt động nếu các trường 'lat' và 'lng' được xác định là Số thay vì chuỗi?
jimijazz

63

Tôi đã gặp sự cố tương tự với mongoose:

fields: 
    [ '[object Object]',
     '[object Object]',
     '[object Object]',
     '[object Object]' ] }

Trên thực tế, tôi đang sử dụng "type" làm tên thuộc tính trong giản đồ của mình:

fields: [
    {
      name: String,
      type: {
        type: String
      },
      registrationEnabled: Boolean,
      checkinEnabled: Boolean
    }
  ]

Để tránh hành vi đó, bạn phải thay đổi tham số thành:

fields: [
    {
      name: String,
      type: {
        type: { type: String }
      },
      registrationEnabled: Boolean,
      checkinEnabled: Boolean
    }
  ]

4
yeah, thậm chí không nghĩ về điều đó. Điều đó đã giải quyết vấn đề của tôi ngay trước khi tôi chuẩn bị bắt đầu đập đồ đạc lên bàn của mình haha, cảm ơn một lần nữa. Kể từ bây giờ, tôi sẽ chỉ tránh 'nhập' trong các lược đồ mongoose của mình.
blackops

Bạn có thể cho một ví dụ về json mà bạn đang cố gắng chèn không?
owensmartin

1
hoặc bạn có thể vượt qua các tùy chọn riêng tư MỞ RỘNG để xây dựng giản đồ của bạn để ghi đè lên tờ khai loại
jimijazz

2

Cảm ơn vì đã trả lời

Tôi đã thử cách tiếp cận đầu tiên, nhưng không có gì thay đổi. Sau đó, tôi cố gắng ghi lại kết quả. Tôi chỉ đi sâu từng cấp độ, cho đến khi cuối cùng tôi đến được nơi dữ liệu được hiển thị.

Sau một thời gian, tôi phát hiện ra vấn đề: Khi tôi gửi phản hồi, tôi đang chuyển đổi nó thành một chuỗi qua .toString().

Tôi đã sửa điều đó và bây giờ nó hoạt động tuyệt vời. Xin lỗi cho các báo động giả.


1

Vấn đề tôi cần giải quyết là lưu trữ các hợp đồng có chứa một vài trường (địa chỉ, sách, num_of_days, vayer_addr, blk_data), blk_data là danh sách giao dịch (số khối và địa chỉ giao dịch). Câu hỏi và câu trả lời này đã giúp tôi. Tôi muốn chia sẻ mã của tôi như dưới đây. Hi vọng điêu nay co ich.

  1. Định nghĩa lược đồ. Xem 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
        }]
    }
);
  1. Tạo bản ghi cho bộ sưu tập trong MongoDB. Xem 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();
            });

        });

    },
];
  1. Cập nhật bản ghi. Xem 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));
        });
    },
];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.