繁体   English   中英

使用 C# 驱动程序使用 Elemmatch 查询 MongoDB

[英]Query MongoDB with Elemmatch using C# driver

我无法将查询(相对简单)从 Mongo Shell 转换为 C#(可以是 linq 或过滤器构建器)。 我想通过某个字段(在我的示例EntityIdActivityDate )和数组上存在的字段(在我的示例UnCommonFields )进行查询。

数据示例:

{ 
    "_id" : ObjectId("5ded105e90424e1c0e6fda05"), 
    "EntryId" : NumberLong(1111111), 
    "EntityId" : "10000007", 
    "EntityType" : NumberInt(5), 
    "ActivityItemId" : "1,4,16172532", 
    "ActivityDate" : ISODate("2015-04-13T03:50:55.000-0400"), 
    "CreateDate" : ISODate("2017-12-13T19:07:07.757-0500"), 
    "UpdateDate" : ISODate("2017-12-13T19:07:07.757-0500"), 
    "ActivityItemStatus" : NumberInt(2), 
    "ActivityTypeId" : NumberInt(2), 
    "Currency" : "USD", 
    "Amount" : "-10.7800", 
    "ActivityItemDescription" : "Stackoverflow example", 
    "DisplayLevel" : NumberInt(10), 
    "UnCommonFields" : [   
        {
            "k" : "CardPresent", 
            "v" : NumberLong(2)
        }, 
        {
            "k" : "PreAuthDate", 
            "v" : ISODate("2015-04-11T08:47:05.000-0400")
        }, 
        {
            "k" : "TransactionDate", 
            "v" : ISODate("2015-04-13T03:50:55.000-0400")
        }, 
        {
            "k" : "ActivityItemStatus", 
            "v" : NumberLong(2)
        }, 
        {
            "k" : "MerchantName", 
            "v" : "StackOverflow POS"
        }, 
        {
            "k" : "TerminalCity", 
            "v" : "TLV"
        }, 
        {
            "k" : "TerminalState", 
            "v" : "IL"
        }, 
        {
            "k" : "TerminalCountry", 
            "v" : "IL"
        }, 
        {
            "k" : "Fee", 
            "v" : 0.0
        }, 
        {
            "k" : "IsDecline", 
            "v" : false
        }, 
        {
            "k" : "BillingAmount", 
            "v" : -10.78
        }, 
        {
            "k" : "BillingCurrency", 
            "v" : "USD"
        }, 
        {
            "k" : "ForeignAmount", 
            "v" : -10.78
        }, 
        {
            "k" : "ForeignCurrency", 
            "v" : "USD"
        }, 
        {
            "k" : "FxRate", 
            "v" : 1.0
        }, 
        {
            "k" : "MaskedCardNumber", 
            "v" : "530000XXXXXX6699"
        }
    ]
}

我想在 Mongo shell 上编写的查询如下所示:

db.getCollection("ActivityWriterTest").find(     
   {$and: 
      [ 
        {EntityId:"10000007"}, 
        { ActivityDate: { $gte: ISODate("2015-04-12T03:50:55.000"), $lte: ISODate("2015-04-14T03:50:55.000") } },
        {UnCommonFields : { $elemMatch : {"k" : "ForeignAmount", "v" : {$in: [-10.78, -15.85] } }}}
      ]
   })

这是我在 C# 代码中编写的部分:它包含两个第一个过滤器,并且按预期工作

_activityContext.ActivityData.Find(x => x.EntityId == accountHolderId && x.ActivityDate >= requestDetails.FromDate && x.ActivityDate <= requestDetails.ToDate)

我尝试以多种方式实现 elemmactch,但没有成功.. 知道如何将 elemmatch 翻译和集成为查询的一部分吗?

我使用 MongoDB 驱动程序 2.10

您还没有展示您的 C# 类的外观,但我假设您将System.Object用于UnCommonFields.v因为那里有不同类型的值。

要构建$elemMatch查询,您需要使用来自 MongDB C# 驱动程序的Builders<T>.Filter .Filter 类型。 假设Model代表您的实体,而Uncommonfield代表嵌套对象,您可以运行以下查询:

var query = Builders<Model>.Filter.And(
                Builders<Model>.Filter.Eq(x => x.EntityId, accountHolderId),
                Builders<Model>.Filter.Gte(x => x.ActivityDate, requestDetails.FromDate),
                Builders<Model>.Filter.Lte(x => x.ActivityDate, requestDetails.ToDate),
                Builders<Model>.Filter.ElemMatch(x => x.UnCommonFields, 
                    Builders<Uncommonfield>.Filter.And(
                        Builders<Uncommonfield>.Filter.Eq(x => x.k, "ForeignAmount"),
                        Builders<Uncommonfield>.Filter.In(f => f.v, new object[]{ -10.78, -15.85 })
                    )
                )
            );

var doc = _mongoDBCollection.Find(query).First();

LINQ版本:

var q = from doc in _mongoDBCollection.AsQueryable()
        where doc.EntityId == accountHolderId
        where doc.ActivityDate >= requestDetails.FromDate
        where doc.ActivityDate <= requestDetails.ToDate
        where doc.UnCommonFields.Any(x => x.k == "ForeignAmount" && new object[] { -10.78, -15.85 }.Contains(x.v))
        select doc;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM