2014-07-21 3 views
3

Я пытаюсь запустить запрос Geo Box с использованием Mongoose, но не получаю никаких результатов. Я построил из упрощенного тестового примера:Geospatial Box query - Mongoose, Node.js MongoDB - не возвращает результатов

var mongoose = require('mongoose'); 

// Schema definition 
var locationSchema = mongoose.Schema({ 
    userid: { type : [Number], required: true}, 
    loc: { 
     'type': { 
      type: String, 
      required: true, 
      enum: ['Point', 'LineString', 'Polygon'], 
      default: 'Point' 
     }, 
     coordinates: [] 
    }, 
    tags: { type : [String], index: true, required: true }, 
    create_date : {type: Date, "default": Date.now()} 
}); 

locationSchema.index({ 'loc.coordinates': '2dsphere' }); 
var Location = mongoose.model('Location', locationSchema); 

mongoose.connect('mongodb://localhost/test'); 

var chkin = new Location({ 
    userid: 1, 
    loc: { type: 'Point', coordinates: [-122.424088, 37.529876] }, 
    tags:"foo" 
}); 

chkin.save(function (err, locations) { 
    console.log('SAVE err: ' + err) 
    console.log('SAVE locations: ' + locations) 
    console.log(''); 
    var query = Location.find(
     { "coordinates" : 
      { "$geoWithin" : 
       // <bottom left coordinates> - <upper right coordinates> - long,lat 
       { "$box" :[[-122.610168,37.598167], [-122.288818,37.845833]] } 
      } 
     }, function (err, docs) { 
      console.log('FIND err: '+ err) 
      console.log('FIND locations: '+docs) 
     }); 
}); 

Консоли вывод:

SAVE err: null 
SAVE locations: { __v: 0, 
    _id: 53cc7a3ea44a9bc70634fdc6, 
    create_date: Sun Jul 20 2014 19:26:06 GMT-0700 (PDT), 
    tags: [ 'foo' ], 
    loc: { coordinates: [ -122.424088, 37.529876 ], type: 'Point' }, 
    userid: [ 1 ] } 

FIND err: null 
FIND locations: 

Может кто-нибудь посоветовать, где моя ошибка?

ответ

15

Есть несколько проблем в том, что вы кодируете здесь. Лучше всего, чтобы посмотреть на весь рабочий список и ломать, что вниз:

var async = require('async'), 
    mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 


var locationSchema = new Schema({ 
    userid: { type: Number, required: true }, 
    loc: { 
    type: { 
     type: "String", 
     required: true, 
     enum: ['Point', 'LineString', 'Polygon'], 
     default: 'Point' 
    }, 
    coordinates: [Number] 
    }, 
    tags: [{ type: String, index: true, required: true }], 
    create_date: { type: Date, default: Date.now } 
}); 

locationSchema.index({ 'loc': '2dsphere' }); 
var Location = mongoose.model('Location', locationSchema); 

mongoose.connect('mongodb://localhost/geotest'); 

async.series(
    [ 

    function(callback) { 
     Location.remove(function(err) { 
     if (err) throw err; 
     callback(); 
     }); 
    }, 

    function(callback) { 
     var loc = new Location({ 
     userid: 1, 
     loc: { 
      type: 'Point', 
      coordinates: [ -122.4481201171875, 37.71370177998719 ] 
     }, 
     tags: "foo" 
     }); 

     loc.save(function(err,loc) { 
     if (err) throw err; 
     console.log("Location: %s", JSON.stringify(loc, undefined, 4)); 
     callback(); 
     }); 
    }, 

    function(callback) { 
     var query = Location.find({ 
     "loc": { 
      "$geoWithin": { 
      "$geometry": { 
       "type": "Polygon", 
       "coordinates": [[ 
       [ -122.610168, 37.598167 ], 
       [ -122.288818, 37.598167 ], 
       [ -122.288818, 37.845833 ], 
       [ -122.610168, 37.845833 ], 
       [ -122.610168, 37.598167 ] 
       ]] 
      } 
      } 
     } 
     }); 
     query.exec(function(err,docs) { 
     if (err) throw err; 
     console.log("Docs: %s", JSON.stringify(docs, undefined, 4)); 
     callback(); 
     }); 
    } 

    ] 
); 

Не напрямую связаны, но, казалось бы, что ты не хотел сделать, как вы определили некоторые элементы в вашей схеме, как это:

userid: { type: [Number], required: true }, 

Это определяет поле как «Массив», и, похоже, вы действительно не имеете в виду в этом случае. Если вы сделали то, что на самом деле имеет больше смысла писать так:

userid: [{ type: Number, required: true }], 

Но ради этого перечисления его просто показано, как равнину. Поле «теги» имеет смысл как массив и определено таким образом.

Следующее, на что нужно обратить внимание, - это определение индекса. Возможно, это было результатом попыток неработающих действий, но, как правило, если вы определяете структуру GeoJSON под «loc» в ваших документах, то это поле, которое вам нужно индексировать. Что, возможно, связано с следующей частью.

locationSchema.index({ 'loc': '2dsphere' }); 

Когда вы запрашиваете на GeoJSON форматированных объектов, помощник оператора, такие как $box не могут быть использованы:

... "Оператор $ коробка возвращает документы на основе координат сетки и не запрашивает для форм GeoJSON ".

Итак, когда вы на самом деле с помощью формате GeoJSON, то вы должны указать в качестве или типа «Полигон» «MultiPolygon» в пределах для того, чтобы соответствовать объекты GeoJSON в пределах этих границ. В любом случае поле, заданное в $geoWithin, должно быть полем, содержащим индекс. Вы, где поставляете «координаты», которые не были действительным полем верхнего уровня. В зависимости от области индекса вы на «LOC» или «loc.coordinates»:

 var query = Location.find({ 
     "loc": { 
      "$geoWithin": { 
      "$geometry": { 
       "type": "Polygon", 
       "coordinates": [[ 
       [ -122.610168, 37.598167 ], 
       [ -122.288818, 37.598167 ], 
       [ -122.288818, 37.845833 ], 
       [ -122.610168, 37.845833 ], 
       [ -122.610168, 37.598167 ] 
       ]] 
      } 
      } 
     } 
     }); 

Наконец, «точка», что искали лежит за пределами «коробки» вы указанием. Здесь «окно» вы искали с и «Точка», показанная вне «коробки»:

enter image description here

Перечень показано выше исправляет все эти вещи и поставляет «точка» и " Полигон "формы с действительно будут соответствовать условиям. Попробуйте работать с такими сайтами, как gejsonlint.com и другими, чтобы проверить правильность данных, с которыми вы работаете.

+1

Это фантастическая ссылка. Спасибо, что нашли время для подробного ответа. –

Смежные вопросы