2012-11-07 34 views
11

Załóżmy, że mam kolekcję z dokumentami z atrybutem ratio będącym liczbą zmiennoprzecinkową.mongodb - Znajdź dokument z najbliższą wartością całkowitą

{'ratio':1.437} 

Jak napisać kwerendę, aby znaleźć jeden dokument z najbliższą wartość dla danej liczby całkowitej bez ładowania je wszystkie do pamięci za pomocą sterownika i znalezieniu jednego z najmniejszą wartością abs(x-ratio)?

Odpowiedz

17

Interesujący problem. Nie wiem, czy można to zrobić w jednym zapytaniu, ale można to zrobić w dwóch:

var x = 1; // given integer 
closestBelow = db.test.find({ratio: {$lte: x}}).sort({ratio: -1}).limit(1); 
closestAbove = db.test.find({ratio: {$gt: x}}).sort({ratio: 1}).limit(1); 

Wtedy po prostu sprawdzić, który z dwóch docs ma ratio najbliżej liczby całkowitej docelowej.

MongoDB 3.2 Aktualizacja

3,2 wydaniu dodano wsparcie dla operatora agregacji $abs wartości absolutne, które teraz pozwala to być zrobione w jednym aggregate zapytania:

var x = 1; 
db.test.aggregate([ 
    // Project a diff field that's the absolute difference along with the original doc. 
    {$project: {diff: {$abs: {$subtract: [x, '$ratio']}}, doc: '$$ROOT'}}, 
    // Order the docs by diff 
    {$sort: {diff: 1}}, 
    // Take the first one 
    {$limit: 1} 
]) 
5

mam inny pomysł, ale bardzo trudne i trzeba zmienić strukturę danych.

Można użyć geolocation index który wspierany przez MongoDB

pierwsze, zmienić swoje dane do tej struktury i utrzymać drugą wartość z 0

{'ratio':[1.437, 0]} 

Następnie można użyć $near operatora, aby znaleźć najbliższy stosunek wartość i ponieważ operator zwraca listę posortowaną według odległości z liczbą całkowitą, którą podajesz, musisz użyć wartości limit, aby uzyskać tylko najbliższą wartość.

db.places.find({ ratio : { $near : [50,0] } }).limit(1) 

Jeśli nie chcesz tego zrobić, myślę, że można po prostu użyć @ odpowiedź JohnnyHK za :)

+0

I rozważał zastosowanie geolokalizacji w ten sposób ... Myślę, że mam zamiar dać ten strzał. Wartość stosunku jest w rzeczywistości współczynnikiem kształtu obrazu, więc mogę traktować szerokość x wysokość jako zapytanie wymiarowe. – DeaconDesperado