4

I used MongoDB's Compass to created a pipeline that I exported to C#, however I am not sure how to use this (tool generates a BsonArray) in the actual code to perform an aggregation? This is a geoNear which isn't currently supported by LINQ, if that has any bearing.

I attempted to use this var result = collection.Aggregate(pipeline); which some documentation suggested (pipeline - is that BsonArray object generated by Compass.

Example of what compass would create:

new BsonArray
{
    new BsonDocument("$geoNear",
    new BsonDocument
        {
            { "near",
    new BsonDocument
            {
                { "type", "Point" },
                { "coordinates",
    new BsonArray
                {
                    -2.11,
                    52.55
                } }
            } },
            { "distanceField", "distanceField" },
            { "maxDistance", 5000 },
            { "spherical", true }
        }),
    new BsonDocument("$sort",
    new BsonDocument("distanceField", -1))
};
metase
  • 1,169
  • 2
  • 16
  • 29

3 Answers3

4

Somehow the currently accepted answer did not worked for me as my compiler says it cannot cast BsonArray to PipelineDefinition, but it led me to a solution that worked for me.

PipelineDefinition<Transport, Transport> pipeline= new []
    {
        new BsonDocument("$geoNear",
        new BsonDocument
            {
                { "near",
        new BsonDocument
                {
                    { "type", "Point" },
                    { "coordinates",
        new BsonArray
                    {
                        -2.11,
                        52.55
                    } }
                } },
                { "distanceField", "distanceField" },
                { "maxDistance", 5000 },
                { "spherical", true }
            }),
        new BsonDocument("$sort",
        new BsonDocument("distanceField", -1))
    };


 //this will now work
 var cursor = await collection.AggregateAsync(pipeline);
 var listResult = await cursor.ToListAsync();

Basically, it wanted a BsonDocument[] instead of a BsonArray

Louie Almeda
  • 5,366
  • 30
  • 38
1

Turns out that using the compass generated code just needed to be strongly typed. For some reason the compiler could not interpret what was going on (contrary to original code idea. So instead of using var a type was required. Seems so trivial now...

so as an example:

 PipelineDefinition<Transport, Transport> pipeline= new BsonArray
    {
        new BsonDocument("$geoNear",
        new BsonDocument
            {
                { "near",
        new BsonDocument
                {
                    { "type", "Point" },
                    { "coordinates",
        new BsonArray
                    {
                        -2.11,
                        52.55
                    } }
                } },
                { "distanceField", "distanceField" },
                { "maxDistance", 5000 },
                { "spherical", true }
            }),
        new BsonDocument("$sort",
        new BsonDocument("distanceField", -1))
    };


 //this will now work
 var cursor = await collection.AggregateAsync(pipeline);
 var listResult = await cursor.ToListAsync();
metase
  • 1,169
  • 2
  • 16
  • 29
0

give this no bsondocument, no magic strings solution a try. change the Cafe class to match your domain entity.

using MongoDB.Driver;
using MongoDB.Entities; // Install-Package MongoDB.Entities

namespace StackOverflow
{
    public class Program
    {
        public class Cafe : Entity
        {
            public string Name { get; set; }
            public Coordinates2D Location { get; set; }
            public double distanceField { get; set; }
        }

        private static void Main(string[] args)
        {
            // connect to mongodb
            new DB("test", "localhost");

            // define an index
            DB.Index<Cafe>()
              .Key(c => c.Location, KeyType.Geo2DSphere)
              .Create();

            // define a search point
            var searchPoint = new Coordinates2D(-2.11, 52.55);

            // initial query
            var query = DB.GeoNear<Cafe>(
                                NearCoordinates: searchPoint,
                                DistanceField: c => c.distanceField,
                                MaxDistance: 50000,
                                Spherical: true)
                          .SortByDescending(c => c.distanceField);

            // add another stage to above query
            var coffeeBeans = query.Match(c => c.Name == "Coffee Bean");

            // retrieve entities
            var result = coffeeBeans.ToList();
        }
    }
}
Dĵ ΝιΓΞΗΛψΚ
  • 5,068
  • 3
  • 13
  • 26