C#MongoDB:在$unwind后查询数组上的$match

C#MongoDB:在$unwind后查询数组上的$match,c#,mongodb,aggregation-framework,mongodb-.net-driver,C#,Mongodb,Aggregation Framework,Mongodb .net Driver,我有一个使用IAggregateFluent执行的聚合管道 下面是与DB的类映射 public class Card { public ObjectId Id { get; set; } public string CardNumber { get; set; } public string CustomerId { get; set; } public decimal BalanceAmount { get; set; }

我有一个使用IAggregateFluent执行的聚合管道

下面是与DB的类映射

public class Card
    {
        public ObjectId Id { get; set; }
        public string CardNumber { get; set; }
        public string CustomerId { get; set; }
        public decimal BalanceAmount { get; set; }
        public string Currency { get; set; }
        public List<CardTransaction> Transactions { get; set; }
    }
如何使用Fluent聚合查询以仅获取与特定OrderNumber匹配的CardTransaction(作为末尾的投影)

这在shell上非常有效,但是如果不使用BsonDocument,将其转换为C#似乎不起作用

db.cards.aggregate([
    {
        $match:{
            CardNumber:"00000001"
        }
    },
    {
        $unwind:"$Transactions"
    },
    {
        $match:{
            "Transactions.OrderNumber":"123456789-1"
        }
    },
    {
        $project:{
            _id:0,
            Transactions:1
        }
    }
])
到目前为止:

    Cards.Aggregate()
    .Match(x => x.CardNumber == someCardNumber)
    .Unwind<Card,Card>(x => x.Transactions)
    .Match(x => x.Transactions.MethodThatReturnsBool
(y=>y.OrderNumber == someOrderNumber))
    .Project(p=>p.Transactions).ToList();
Cards.Aggregate()
.Match(x=>x.CardNumber==someCardNumber)
.diswind(x=>x.Transactions)
.Match(x=>x.Transactions.MethodThatReturnsBool
(y=>y.OrderNumber==someOrderNumber))
.Project(p=>p.Transactions).ToList();

您可以在
IMongoCollection
上运行
.AsQueryable()
,然后运行以下LINQ查询:

var q = from card in Cards.AsQueryable()
        where card.CardNumber == "00000001"
        select card.Transactions.Where(tran => tran.OrderNumber == "123456789-1");

var data = q.ToList();
它生成以下聚合管道:

{
    "$match" : {
        "CardNumber" : "00000001"
    }
},
{
    "$project" : {
        "__fld0" : {
            "$filter" : {
                "input" : "$Transactions",
                "as" : "tran",
                "cond" : {
                    "$eq" : [
                        "$$tran.OrderNumber",
                        "123456789-1"
                    ]
                }
            }
        },
        "_id" : 0
    }
}

这里有一种使用包装器库处理一对多关系的替代方法

using System.Linq;
using MongoDB.Entities;

namespace StackOverflow
{
    public class Card : Entity
    {
        public string Number { get; set; }
        public One<Customer> Customer { get; set; }
        public Many<Transaction> Transactions { get; set; }

        public Card() => this.InitOneToMany(() => Transactions);
    }

    public class Transaction : Entity
    {
        public string OrderNumber { get; set; }
    }

    public class Customer : Entity
    {
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new DB("orders-test");

            var customer = new Customer { Name = "Customer 1" };
            customer.Save();

            var card = new Card { Number = "00000001", Customer = customer.ToReference() };
            card.Save();

            var transaction = new Transaction { OrderNumber = "12345" };
            transaction.Save();

            card.Transactions.Add(transaction);

            var transactions = DB.Collection<Card>()
                                 .Where(c => c.Number == "00000001")
                                 .SingleOrDefault()
                                 .Transactions.Collection()
                                              .Where(t => t.OrderNumber == "12345")
                                              .ToList();
        }
    }
}

LINQ查询将所有内容包装到IQueryable中,因此最后我得到了一个
IQueryable
。如何提取事务?(LINQ新成员)
using System.Linq;
using MongoDB.Entities;

namespace StackOverflow
{
    public class Card : Entity
    {
        public string Number { get; set; }
        public One<Customer> Customer { get; set; }
        public Many<Transaction> Transactions { get; set; }

        public Card() => this.InitOneToMany(() => Transactions);
    }

    public class Transaction : Entity
    {
        public string OrderNumber { get; set; }
    }

    public class Customer : Entity
    {
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new DB("orders-test");

            var customer = new Customer { Name = "Customer 1" };
            customer.Save();

            var card = new Card { Number = "00000001", Customer = customer.ToReference() };
            card.Save();

            var transaction = new Transaction { OrderNumber = "12345" };
            transaction.Save();

            card.Transactions.Add(transaction);

            var transactions = DB.Collection<Card>()
                                 .Where(c => c.Number == "00000001")
                                 .SingleOrDefault()
                                 .Transactions.Collection()
                                              .Where(t => t.OrderNumber == "12345")
                                              .ToList();
        }
    }
}
{ "$match" : 
    { "ParentID" : ObjectId("5cd5ac4c921e4323701995b0") } }, 
    { "$lookup" : { "from" : "Transactions",
                    "localField" : "ChildID", 
                    "foreignField" : "_id", "as" : "children" } }, 
    { "$unwind" : "$children" }, 
    { "$project" : { "children" : "$children", "_id" : 0 } }, 
    { "$match" : { "children.OrderNumber" : "12345" } }