Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongodb: finding the highest numeric value of a column

Tags:

find

php

mongodb

I have MongoDB collection of documents containing several fields. One of the columns/fields should be numeric only, but some of these fields contain non-numerical (corrupt) data as string values. I should find the highest numerical value of this column, excluding the corrupt, non-numerical data. I am aware of the question Getting the highest value of a column in MongoDB, but AFAIK, this extended case was not covered.

The example below depicts the issue. For the highest value, the document with "age": 70 should be returned:

[
{
    "id": "aa001",
    "age": "90"
},
{
    "id": "bb002",
    "age": 70
},
{
    "id": "cc003",
    "age": 20,
}
]

Providing a PHP example for the find() / findOne() query would be of much help. Thanks a lot!

JohnnyHK came up with the perfect solution. Here's the working PHP code:

$cursor = $collection->find(array('age' => array('$not' => array('$type' => 2))), array('age' => 1));
$cursor->sort(array('age' => -1))->limit(1);
like image 928
martti Avatar asked Feb 25 '13 17:02

martti


People also ask

What is $first in MongoDB?

This means $first returns the first order type for the documents between the beginning of the partition and the current document.

How does MongoDB calculate min max?

You need to use the . aggregate() method for it to work. For very large collections aggregating pipeline can be very slow because it scans each document. The solution mentioned here can be better if you need to find min/max of the indexed field: stackoverflow.com/a/6360583/3438640 Use find with sort and limit: db.

What is $Not in MongoDB?

$not performs a logical NOT operation on the specified <operator-expression> and selects the documents that do not match the <operator-expression> . This includes documents that do not contain the field .


2 Answers

You can use the $type operator with $not in your query to exclude docs where age is a string. In the shell your query would look like:

db.test.find({age: {$not: {$type: 2}}}).sort({age: -1}).limit(1)

Or in PHP from Martti:

$cursor = $collection->find(array('age' => array('$not' => array('$type' => 2))), array('age' => 1));
$cursor->sort(array('price' => -1))->limit(1);
like image 107
JohnnyHK Avatar answered Oct 13 '22 12:10

JohnnyHK


with PHP driver (mongodb)
using findOne()

$filter=[];
$options = ['sort' => ['age' => -1]]; // -1 is for DESC
$result = $collection->findOne(filter, $options);
$maxAge = $result['age']
like image 36
Albert s Avatar answered Oct 13 '22 13:10

Albert s