MongoDB: использование агрегата с $ geoNear не возвращает все результаты - Node.js - PullRequest
0 голосов
/ 08 октября 2018

При использовании geoNear агрегат не возвращает все результаты, которые он должен вернуть.Я дважды проверил, и есть некоторые результаты, которые находятся в диапазоне и соответствуют запросу, но не возвращаются.Только 18 возвращаются, где я должен получить 30 ...

Документы, которые нужно получить, являются репетиторами, у которых есть диапазон (значение int), соответствующий тому, как далеко они будут двигаться.И если клиент ищет, например, репетитора на 48 rue de Varenne, Paris, мы должны получить только тех репетиторов, которые могут перейти на 48 rue de Varenne, Paris ( расстояние между местом поиска иМестоположение репетитора меньше диапазона репетитора )

Это запрос:

aggregate = Tutor.aggregate([
  {
    "$geoNear":
    {
      "near":
      {
        "type": "Point",
        "coordinates": [lon1, lat1]
      },
      "distanceField": "distance",
      "spherical": true,
      "maxDistance": radius
    }
  },
  {
    $match: match
  }
]);

Вы знаете, почему я получил эту проблему?Я где-то читал, это может быть из-за слишком большого размера документа?Однако я не знаю, как я могу это проверить.

Большое спасибо за вашу помощь!

PS: Если вы хотите увидеть полный метод:

exports.search = (req, res) => {
  let lat1 = req.body.lat;
  let lon1 = req.body.lng;
  let page = req.body.page || 1;
  let perPage = req.body.perPage || 10;
  let radius = req.body.radius || 10000;

  let levelsIn = req.body.levels && req.body.levels.length !== 0 ? req.body.levels.map(level => {
    return ObjectID(level);
  }) : null;
  let subjectsIn = req.body.subjects && req.body.subjects.length !== 0 ? req.body.subjects.map(subject => {
    return ObjectID(subject);
  }) : null;

  var options = { page: page, limit: perPage,  sortBy: { updatedDate: -1 } }

  const isAdmin = req.user ? req.user.role === "admin" || req.user.role === "super-admin" : false;

  let match = {}

  if (levelsIn) match.levels = { $in: levelsIn };
  if (subjectsIn) match.subjects = { $in: subjectsIn }
  if (typeof req.body.activated !== "undefined") match.profileActivated = req.body.activated;
  if (req.body.from) match.createdAt = { $gte: new Date(req.body.from) };
  if (req.body.to) {
    if (match.createdAt) match.createdAt.$lte = new Date(req.body.to);
    else match.createdAt = { $lte: new Date(req.body.to) };
  }

  var aggregate = null;

  if (!isAdmin) {
    match.activated = true
    match.profileActivated = true
    match.profileOnline = true
  }

  if (lat1 && lon1) {

    aggregate = Tutor.aggregate([
      {
        "$geoNear":
        {
          "near":
          {
            "type": "Point",
            "coordinates": [lon1, lat1]
          },
          "distanceField": "distance",
          "spherical": true,
          "maxDistance": radius
        }
      },
      {
        $match: match
      }
    ]);
  } else {
    aggregate = Tutor.aggregate([
      {
        $match: match
      }
    ]);
  }

  Tutor
    .aggregatePaginate(aggregate, options, function (err, result, pageCount, count) {
      if (err) {
        return res.status(400).send(err);
      }
      else {

        var opts = [
          { path: 'levels', select: 'name' },
          { path: 'subjects', select: 'name' },
          { path: 'assos', select: 'name' }
        ];
        Tutor
          .populate(result, opts)
          .then(result2 => {
            return res.send({
              page: page,
              perPage: perPage,
              pageCount: pageCount,
              documentCount: count,
              tutors: result2
            });
          })
          .catch(err => {
            return res.status(400).send(err);
          });
      }
    })
};

И упрощенную версию модели язапрос:

import mongoose from 'mongoose';
import validate from 'mongoose-validator';
import { User } from './user';
import mongooseAggregatePaginate from 'mongoose-aggregate-paginate';

var ObjectId = mongoose.Schema.Types.ObjectId;


var tutorSchema = mongoose.Schema({
    location: {
        address_components: [
            {
                long_name: String,
                short_name: String,
                types: String
            }
        ],
        description: String,
        lat: Number,
        lng: Number

    },
    range: {
        type: Number,
        default: 15
    },
    loc: {
        type: { type: String },
        coordinates: []
    }
});

tutorSchema.plugin(mongooseAggregatePaginate);
tutorSchema.index({ "loc": "2dsphere" });
module.exports = {
    Tutor
};
...