使用mongoose进行复杂查询,包括子文档,接近条件,

时间:2015-02-24 15:45:06

标签: node.js mongodb mongoose

我有一个非常(至少对我来说)使用Mongoose的复杂查询。

首先我的架构:

var ObjectSchema = new Schema({
    pickupStartDate: {type: Date, required: true, default: Date},
    pickupEndDate: {type: Date, required: true, default: Date},

    ...

    handoverStartDate: {type: Date, required: true, default: Date},
    handoverEndDate: {type: Date, required: true, default: Date},

    ...
});

通过使用“插件机制”,我的对象有两个地址(称为pickupAddresshandoverAddress。地址如下:

var name = 'address';

var obj = {};
obj[name] = {
    street: String,
    zipCode: String,
    city: String,
    state: String,
    country: String,
    loc: {type: [Number], index: '2dsphere'}
};
schema.add(obj);

另一个架构:

var TripSchema = new Schema({
    startDate: {type: Date, required: true, default: Date},
    endDate: {type: Date, required: true, default: Date},
    handoverRadius: {type: Number, required: true}
});

它也有address(再次使用插件机制)。

我想要以下查询:

找到“适合”我旅行的所有“物品”。 “适合”意味着:

  • handoverStartDate >= trip.startDate
  • handoverEndDate <= trip.endDate
  • `handoverAddress接近trip.address
  • ...

我认为这是一个很好的方法:

ObjectSchema
    .find()
    .and([
        { handoverStartDate:    {$gte: trip.startDate}},
        { handoverEndDate:      {$lte: trip.endDate}},
        { 'handoverAddress.loc':  {$near: {
            '$maxDistance': 10 * 1000,
            '$center': {
                type: 'Point',
                coordinates: trip.address.loc
            }
        }}}
    ])
    .exec(function(err, cdObjects) {
        console.log(err);
        console.log(cdObjects);
    });

但这会导致以下错误:

{ message: 'Cast to number failed for value "[object Object]" at path "handoverAddress.loc"'

我猜是因为'handoverAddress.loc'。但是我不知道如何指定它,因为它必须是一个字符串(因为它是一个子文档)。

2 个答案:

答案 0 :(得分:1)

你不需要和。试试

ObjectModel.find({
  handoverStartDate:    {$gte: trip.startDate},
  handoverEndDate:      {$lte: trip.endDate},
  'handoverAddress.loc': {
    $near: {
      $geometry: {
        type: "Point",
        coordinates: trip.address.loc
      },
      $maxDistance: 10 * 1000
    }
})

确保将trip定义为变量,startDate,endDate和address都是符合您期望的已定义属性。

答案 1 :(得分:0)

这就是我的工作方式:

ObjectSchema
    .where('handoverStartDate').gte(trip.startDate)
    .where('handoverEndDate').lte(trip.endDate)
    .where('handoverAddress.loc').near({
        center: {
            type: 'Point',
            coordinates: trip.address.loc
        },
        maxDistance: 10 * 1000
    });