6

Mongoose バージョン: 3.6 ノード バージョン: 0.10

私は何時間もこの問題を解決しようとしてきました。maxDistance よりもいくつかの座標に近いすべてのドキュメントを見つけたいです。距離をメートル単位で入力できるように、MongoDB (2dsphere) の GeoJSON 仕様を使用しようとしています。

これは私のスキーマ「venue.js」です。

var db = require('mongoose'),
    Schema = db.Schema,
    ObjectId = Schema.ObjectId;

var venueSchema = new Schema({
    geo: { type: [Number], index: '2dsphere'},
    city: String,
    name: String,
    address: String
});


module.exports = db.model('Venue', venueSchema);

これは、クエリ ctrlVenue.js を挿入する場所です。

var Venue = require('../models/venue.js');


VenueController = function(){};

/** GET venues list ordered by the distance from a "geo" parameter. Endpoint: /venues
    Params:
        - geo: center for the list of venues - longitude, latitude (default: 25.466667,65.016667 - Oulu);
        - maxDistance: maxímum distance from the center for the list of venues (default: 0.09)
**/
exports.getVenues =function(req, res) {

    var maxDistance = typeof req.params.maxDistance !== 'undefined' ? req.params.maxDistance : 0.09; //TODO: validate
    var geo  =  typeof req.params.geo !== 'undefined' ? req.params.geo.split(',') : new Array(25.466667, 65.016667); //TODO: validate

    var lonLat = { $geometry :  { type : "Point" , coordinates : geo } };


    Venue.find({ geo: {
        $near: lonLat,
        $maxDistance: maxDistance
    }}).exec(function(err,venues){
        if (err)
            res.send(500, 'Error #101: '+err);
        else 
            res.send(venues);
        }); 
    }

コードを実行すると、次のエラーが表示されます。

「エラー #101: CastError: パス \"geo\" の値 \"[オブジェクト オブジェクト]\" の数値へのキャストに失敗しました"

代わりにこの行を変更すると:

$near: lonLat,

$near: geo,

書類を正しく取得しましたが、測定単位としてメートルを使用できません。次の表に基づいて仮定しました: http://docs.mongodb.org/manual/reference/operator/query-geospatial/

$geometryを使用して機能する例をたくさん見てきましたが、 $nearと一緒に使用した例はありません。私は何を間違っていますか?

4

1 に答える 1

3

型を使用する必要があり、Mixedカスタム検証を追加して、値が配列であり、長さが 2 であることを確認しました。また、空の配列をチェックし、それらをnullsに変換しました2dsphere。(Mongoose は配列フィールドを [] に設定しますが、これは有効な座標ではありません!)

var schema = new mongoose.Schema({
  location: { type: {}, index: '2dsphere', sparse: true }
});

schema.pre('save', function (next) {
  var value = that.get('location');

  if (value === null) return next();
  if (value === undefined) return next();
  if (!Array.isArray(value)) return next(new Error('Coordinates must be an array'));
  if (value.length === 0) return that.set(path, undefined);
  if (value.length !== 2) return next(new Error('Coordinates should be of length 2'))

  next();
});
于 2013-09-13T18:09:15.063 に答える