Hoe object in array correct te definiëren in Mongoose-schema met 2d geo-index

Ik heb momenteel problemen met het maken van een schema voor het onderstaande document. Het antwoord van de server retourneert altijd de “trk”-veldwaarden als [Object]. Op de een of andere manier heb ik geen idee hoe dit zou moeten werken, aangezien ik in ieder geval alle benaderingen heb geprobeerd die voor mij logisch waren 😉

Als dit helpt, is mijn Mongoose-versie 3.6.20 en MongoDB 2.4.7
En voordat ik het vergeet, zou het leuk zijn om het ook in te stellen als Index (2d)

Oorspronkelijke gegevens:

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

Mangoeste-schema:

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

Het antwoord van het tabblad Netwerk in Chrome ziet er altijd als volgt uit (dat is alleen het trk-gedeelte dat fout is):

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

Ik heb al verschillende Schema-definities voor “trk” geprobeerd:

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

Ik hoop dat je me kunt helpen 😉


Antwoord 1, autoriteit 100%

U kunt trk op de volgende manieren declareren: –
ofwel

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

of

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

In het tweede geval maakt u tijdens het invoegen het object en duwt u het in de array zoals

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

of u kunt de array van object instellen door

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

Antwoord 2, autoriteit 24%

Ik had een soortgelijk probleem met mangoest:

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

In feite gebruikte ik “type” als eigenschapnaam in mijn schema:

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

Om dat gedrag te voorkomen, moet u de parameter wijzigen in:

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

Antwoord 3

Het probleem dat ik moet oplossen is het opslaan van contracten die een paar velden bevatten (adres, boek, aantal_dagen, lener_addr, blk_data), blk_data is een transactielijst (bloknummer en transactieadres).
Deze vraag en het antwoord hebben me geholpen. Ik wil graag mijn code delen zoals hieronder. Ik hoop dat dit helpt.

  1. Schemadefinitie. Zie 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. Maak een record voor de collectie in de MongoDB. Zie 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. Een record bijwerken. Zie 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));
        });
    },
];

Antwoord 4

Voor het maken van een array in schema moeten we nog een schema maken als monetizationSchemadat wordt gebruikt om één gegevens tegelijk op te slaan en een andere als blogSchemawe hebben monetizationmet monetizationSchematussen vierkante haken als een array.

Schemavoor het opslaan van één gegevens tegelijk.

const monetizationSchema = new Schema({
      amazonUrl: {
        type: String,
        required: true,
      } 
    });

Schema met monetizationals een array.

const blogSchema = {
  monetization: [
   monetizationSchema
  ],
  image: {
   type: String,
   required: true
  },
  // ... etc
});

Antwoord 5

Bedankt voor de antwoorden.

Ik heb de eerste benadering geprobeerd, maar er veranderde niets. Vervolgens probeerde ik de resultaten te loggen. Ik ging gewoon niveau voor niveau naar beneden, totdat ik eindelijk kwam waar de gegevens werden weergegeven.

Na een tijdje vond ik het probleem: toen ik het antwoord verzond, converteerde ik het naar een string via .toString().

Ik heb dat opgelost en nu werkt het uitstekend. Sorry voor het valse alarm.

Other episodes