Search code examples
mongodbmongoosekeystonejs

Find documents with unique field


I have a collection of addresses with a geo field (lng/lat). Now I want to get documents with unique geo lng/lat pairs to populate a Google map instance with pins. So naturally I don't want multiple pins sitting in top of each other, so I need to get unique lng/lat pairs only.

var mongoose = require("mongoose"),
    Schema = mongoose.Schema;

var VenueSchema = new Schema({
    name: String,
    street: String,
    streetNumber: String,
    postCode: String,
    suburb: String,
    state: String,
    geo: Array, // [lng, lat]
});

var Venue = mongoose.model('Venue', VenueSchema);

Using the distinct operator, I can easily get all unique lng/lat. Unfortunately this query returns an array of lng/lat geo points and not documents with fields. So I have no idea which business name belongs to what geo point.

keystone.list('Venue').model.find().distinct('geo')
    .exec(function(err, venues){

        if(err){
            throw err;
        }

        console.log(venues); // Array of lat/lng pairs
});

How do I construct a query so I get actual documents with all the fields where no two geo locations are the same?


Solution

  • You can use an aggregate pipeline that uses $group to provide distinct-like behavior but with more flexibility:

    keystone.list('Venue').model.aggregate([
        // Group the docs by the geo field, taking the first doc for each unique geo
        {$group: {
            _id: '$geo',
            doc: { $first: '$$ROOT' }
        }}
    ], callback);
    

    $$ROOT is a system variable that contains the input document of the pipeline stage. So this gives the first document of each unique geo value.