K
K
Konstantin Kitmanov2015-06-17 18:47:25
Laravel
Konstantin Kitmanov, 2015-06-17 18:47:25

How to find almost equal angles in MongoDB?

In MongoDB, there are objects that have one of the properties - the angle in degrees, integers from 0 to 359 (to be completely honest, this is the azimuth).
I need to find objects whose angle differs from the given one by no more than 22.5 degrees. The first version is:

var directionTolerance = 45 / 2;

var query = {
    $or: [
        {
            direction: {
                $gte: newDirection - directionTolerance, // newDirection -- искомый угол
                $lte: newDirection + directionTolerance
            }
        },
        {
            direction: {
                $gte: 360 + newDirection - directionTolerance,
                $lte: 360 + newDirection + directionTolerance
            }
        },
        {
            direction: {
                $gte: 360 - newDirection - directionTolerance,
                $lte: 360 - newDirection + directionTolerance
            }
        }
    ]
};

Unfortunately, this request sometimes gives false positive: for example, it can return an object with an angle of 0 when the angle in the request is 173.
How to do it right?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
L
lega, 2015-06-17
@k12th

The "$or" operation is slow, you can throw it out and do it like this - store the coordinate in several sections:
{
direction: 350,
direction_index: [-10, 350]
}
and search already by index:
.find({direction_index: { $lte: -22, $gte: 22}})
in the end you need the filter to fit into -360..360

M
Mikhail Osher, 2015-06-17
@miraage

I have no idea, but are there sines / cosines? Can trigonometry help?

P
Philipp, 2015-06-17
@zoonman

Typically, NoSQL uses pre-quantification of data.
Those. you have an error of π/8, and a circle of 2π, then your quantifier will be an array from 0 to 16. Each object will have a quantified_direction property that stores the desired value and the selection will be primitive.
A simpler explanation - break the circle into 16 sectors and write the number for each sector directly into the object. When searching, just use this number. You can also increase the value to 32 and search two sectors at the same time. After building an index for quantified_direction , you will get split-second results on huge databases.
But in general, you have an error in the preparation of the condition. Draw a circle, cut out a sector from paper and work with boundary conditions. The task is really simple.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question