根据特定子类型类型的元素匹配查找 MongoDB 文档

Find a MongoDB document based on element match of a specific subtype type

我正在使用 Mongo C# 驱动程序版本 2.2.3 连接到 Mongo 3.0.6 服务器。

给定 MongoDb 人 class 的集合(见下文)我想找到电子邮件地址为 "not@home.com" 的人。有点天真,我曾希望像这样的东西会起作用:

var people = database.GetCollection<Person>("People");

var person = from p in people.AsQueryable()
where p.Addresses.OfType<EmailAddress>().Any(e=>e.MailTo == "not@home.com")

但是在运行时,我收到 NotSupportedException。表达式树不支持 OfType 方法。

是否有一种简单的方法来元素匹配(使用强类型)多态数组?

(这是模型)

class Person
{
    public Address[] Addresses {get;set;}
}
class Address
{
}
class Phone : Address
{
    public string Number {get;set;}
}
class Email : Address
{
    public string MailTo {get;set;}
}

我要查找的示例文档是:

{
        "_id" : ObjectId("56d76465b27c42eb491aa2e7"),
        "Addresses" : [
                {
                        "_t" : "Email",
                        "MailTo" : "not@home.com"
                },
                {
                        "_t" : "Phone",
                        "Number" : "555-1234"
                }
        ]
}

好吧,虽然 C# 驱动程序没有完全实现并且缺少很多功能,但我认为问题出在您的 class 结构中。

例如一个 Person 对象将有地址,地址可能是 Phone 或 Email 类型,甚至两者兼而有之。这就是驱动程序抱怨的地方,因为它无法理解可能存在的对象类型。

因为它本质上更动态,所以我建议您使用 BsonDocument 类型来查询,而不是类型转换为您想要的任何对象。表示您获得结果的选项很少

选项#1:

如果执行以下代码:

var mailTo = "not@home.com";
var filter = Builders<BsonDocument>.Filter.ElemMatch("Addresses",
    Builders<BsonDocument>.Filter.Eq("MailTo", mailTo));

var people = database.GetCollection<BsonDocument>("People");

var person  = people.FindSync(filter).ToList();

您将在子文档中获得包含 not@hotme.com 的记录。

选项#2:

如果您可以稍微更改模型,则可以充分利用 linq 查询。

public class Person
{
    public ObjectId Id { get; set; }
    public Address[] Addresses { get; set; }
}

public class Address
{
    public string MailTo { get; set; }
    public string Number { get; set; }
}   

var mailTo = "not@home.com";
var filter = Builders<Person>.Filter.ElemMatch(e => e.Addresses, 
    address => address.MailTo == mailTo );

var people = database.GetCollection<Person>("People");
var person  = people.FindSync<Person>(filter).ToList();

现在 person 将拥有一个或多个符合您条件的 Person 对象。

你好,这在 2.2.4 中已经修复 请参阅 mongodb jira entry