如何在 C# 中使用 MongoDB Compass 生成的管道到 运行 聚合管道

How to use MongoDB Compass' generated pipeline in C# to run aggregation pipeline

我使用 MongoDB 的 Compass 创建了一个导出到 C# 的管道,但是我不确定如何在实际代码中使用它(工具生成 BsonArray)来执行聚合?这是 LINQ 当前不支持的 geoNear,如果有任何影响的话。

我试图使用 var result = collection.Aggregate(pipeline); some documentation 建议的(管道 - 是 Compass 生成的 BsonArray 对象。

指南针创建的示例:

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))
};

试试这个没有 bsondocument,没有魔法字符串的解决方案。更改 Cafe class 以匹配您的域实体。

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

namespace Whosebug
{
    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();
        }
    }
}

事实证明,使用指南针生成的代码只需要强类型化。出于某种原因,编译器无法解释正在发生的事情(与 original code idea 相反。因此,不是使用 var 而是需要一个类型。现在看起来很微不足道...

举个例子:

 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();

不知何故,当前接受的答案对我不起作用,因为我的编译器说它不能将 BsonArray 转换为 PipelineDefinition,但它让我找到了一个适合我的解决方案。

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();

基本上,它想要一个 BsonDocument[] 而不是 BsonArray