1

I am on symfony and I want a list of documents based on some latitude and longitude.

Here are my classes :

<?php
// src/GameBundle/Document/Store.php

namespace GameBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Document(repositoryClass="GameBundle\Repository\StoreRepository") 
 * @MongoDB\Index(keys={"coordinates"="2d"})
 */
class Store
{
  /**
   * @MongoDB\Id(strategy="AUTO")
   */
  protected $id;

  /**
   * @MongoDB\ReferenceOne(targetDocument="GameBundle\Document\Company")
   */
  protected $company;

  /**
   * @MongoDB\Field(type="string")
   */
  protected $name;

  /**
   * @MongoDB\EmbedOne(targetDocument="GameBundle\Document\Coordinates")
   */
  protected $coordinates;

  /**
   * @MongoDB\Field(type="string")
   */
  protected $phone;

  /**
   * @MongoDB\Field(type="string")
   */
  protected $email;

  /**
   * @MongoDB\Field(type="string")
   */
  protected $logo;

  /**
   * @MongoDB\Field(type="string")
   */
  protected $description;

and my Coordinate Class

<?php

namespace GameBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\EmbeddedDocument
 */
class Coordinates
{

  public function __construct($long, $lat) {
        $this->setX($long);
        $this->setY($lat);
    }

    /**
     * @MongoDB\Field(type="float")
     */
    protected $x;

    /**
     * @MongoDB\Field(type="float")
     */
    protected $y;

and finally my repository

<?php
namespace GameBundle\Repository;

use GameBundle\Document\Store;
use Doctrine\ODM\MongoDB\DocumentRepository;
/**
 * Game Repository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class StoreRepository extends DocumentRepository
{
  public function findIfExistNear($company, $long, $lat) {
    $qb = $this->createQueryBuilder()
          ->field('company')->references($company)
          ->field('coordinates')->near($long, $lat);

    $query = $qb->getQuery();

    return $query->execute()->toArray(false);
  }
}

In my controller

$store = $em->getRepository('GameBundle:Store')->findIfExistNear($company, $long, $lat);

$view = $this->view($store);
return $this->handleView($view);

And here the response when I call the route with postman

"message": "$geometry is required for geo near query",

Can someone help me, I think I follow this example: exemple but I can't get it work. Thank you.

EDIT

Tried with an array and I have the same error. Here is one of my document

{
  "_id" : ObjectId("5b07ddbd5d83ea08080014b3"),
  "company" : DBRef("Company", ObjectId("5b07ddbd5d83ea0808001477"), "cdn"),
  "name" : "Restaurant2",
  "coordinates" : [ 43.48237556880739, -1.5671825408935547 ],
  "phone" : "0102030405",
  "email" : "Restaurant2@gmail.com"
}

Here is the result of db.Store.getIndexes()

[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "cdn.Store"
        },
        {
                "v" : 1,
                "key" : {
                        "coordinates" : "2d"
                },
                "name" : "coordinates_2d",
                "sparse" : false,
                "ns" : "cdn.Store"
        }
]

and here the query I found in the logs

MongoDB query: {
"find":true,
"query":{
"company.$id":{"$id":"5b07ddbd5d83ea0808001471"},
"coordinates":{"$near":["-0.3580964000000222","43.31650579999999"]}},
"fields":[],
"db":"cdn","collection":"Store"
}

Tries this command in shell: > db.Store.find({"company.$id" : ObjectId("5b07ddbd5d83ea0808001471"), "coordinates": {$near: [-105. 06055001328127, 49.28511456161271]}})

And I get a result, but I should not because those coordinates are in America and my store in France...

PART OF THE SOLUTION

use GameBundle\Document\Store;
use Doctrine\ODM\MongoDB\DocumentRepository;
/**
 * Game Repository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class StoreRepository extends DocumentRepository
{
  public function findIfExistNear($company, $long, $lat) {
    $qb = $this->createQueryBuilder()
           ->field('company')->references($company)
  ---      ->field('coordinates')->near($long, $lat);
  +++      ->field('coordinates')->near((float) $long,(float) $lat);

    $query = $qb->getQuery();

    return $query->execute()->toArray(false);
  }
}
Arcades
  • 150
  • 1
  • 13
  • I did what you say and yes it does not look like the query it should : [$near](https://docs.mongodb.com/manual/reference/operator/query/near/) . But is that not the purpose of the odm near function to add in the query that $geometry, etc ? – Arcades May 25 '18 at 10:31
  • Definitely something wrong here, and it does help a lot that you are actually logging the query so people can see what is happening. Just to be sure that's not just the "logger" doing some weird format ( though it probably is not ) you might want to confirm what MongoDB receives as well. You might check out [Enabling Profiling](https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/) and seeing if the same statement is there as well. Also try running a query in the shell at least to see the results. This would all help for someone more familiar with Doctrine Mongo setup. – Neil Lunn May 25 '18 at 10:37
  • Try some command in shell but get results in all cases event if I put really far coordinates... – Arcades May 25 '18 at 12:46
  • Man I just found why it did not work, $lat and $long were string, if I force the type with (float) I have results. But now it send me result whatever lat and long I set, maybe there is a range property to add for the circle around that point – Arcades May 25 '18 at 13:06

0 Answers0