对于使用MongoDB C#Driver 2.0的某些属性,C#中的聚合确实返回null
我正在编写一个MongoDB应用程序,并在C#fow复杂查询中使用聚合管道。 当我将C#生成的聚合复制到shell中时,一切似乎都很好。但是,在C#中执行聚合时,某些属性被设置为对于使用MongoDB C#Driver 2.0的某些属性,C#中的聚合确实返回null,c#,mongodb,mongodb-query,C#,Mongodb,Mongodb Query,我正在编写一个MongoDB应用程序,并在C#fow复杂查询中使用聚合管道。 当我将C#生成的聚合复制到shell中时,一切似乎都很好。但是,在C#中执行聚合时,某些属性被设置为null。有关更多信息,请参见下文 首先,让我向您展示我的模型: public class Smartphone { #region Properties [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; }
null
。有关更多信息,请参见下文
首先,让我向您展示我的模型:
public class Smartphone
{
#region Properties
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("name")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Name { get; set; }
[BsonElement("description")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Description { get; set; }
[BsonElement("typenr")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Type { get; set; }
[BsonElement("props")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public List<SmartphoneProperty> Properties { get; set; }
#endregion
}
public class UnwindedSmartphone
{
#region Properties
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("name")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Name { get; set; }
[BsonElement("description")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Description { get; set; }
[BsonElement("typenr")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Type { get; set; }
[BsonElement("props")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public SmartphoneProperty Property { get; set; }
#endregion
}
public class SmartphoneProperty
{
#region Properties
[BsonElement("type")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Type { get; set; }
[BsonElement("value")]
[BsonIgnoreIfNull]
[BsonIgnoreIfDefault]
public string Value { get; set; }
#endregion
}
需要执行的聚合命令如下所示:
{
"_id" : ObjectId("55d45c0285afc59c146f66f0"),
"name" : "LG Nexus 6",
"description" : "A Nexus 6 device, created by Google.",
"typenr" : "LG-NEX-5/BLACK",
"props" : [
{
"type" : "os",
"value" : "Android"
},
{
"type" : "storage",
"value" : "8"
},
{
"type" : "storage",
"value" : "16"
},
{
"type" : "storage",
"value" : "32"
},
{
"type" : "storage",
"value" : "64"
}
]
}
// Get all the amount of filters that are defined.
db.smartphones.aggregate([
// Unwind the "props".
{ "$unwind" : "$props" },
// Grouping phase.
// Group by unique properties, add a count for the amount of articles, and add articles to an element named "articles".
// We use the function "$addToSet" here to ensure that only unique articles are being added.
{
"$group" : {
"_id" : "$props",
count : { "$sum" : 1 },
articles: {
"$addToSet": {
name: "$name",
description: "$description",
typenr: "$typenr"
}
}
}
},
// Sort the results based on the "_id" field.
{ "$sort" : { "_id" : 1 } }
]);
"_id" : {
"type" : "storage",
"value" : "128"
},
"count" : 1.0000000000000000,
"articles" : [
{
"name" : "Apple iPhone 6",
"description" : "An iPhone 6 device, created by Apple.",
"typenr" : "APP-IPHONE-6/BLACK"
}
]
// Get all the amount of filters that are defined.
db.smartphones.aggregate([
// Unwind the "props".
{ "$unwind" : "$props" },
// Grouping phase.
// Group by unique properties, add a count for the amount of articles, and add articles to an element named "articles".
// We use the function "$addToSet" here to ensure that only unique articles are being added.
{
"$group" : {
"_id" : "$props",
"count" : { "$sum" : 1 },
"articles" : {
"$addToSet" : {
"name" : "$name",
"description" : "$description",
"typenr" : "$typenr"
}
}
}
},
{ "$sort" : { "_id" : 1 } }
])
var aggregation = collection.Aggregate()
.Unwind<Smartphone, UnwindedSmartphone>(x => x.Properties)
.Group(key => key.Property, g => new
{
Count = g.Count(),
Articles = g.Select(x => new AggregatedSmartphoneArticle
{
Name = x.Name,
Description = x.Description,
Type = x.Type
}).Distinct()
});
此聚合的单个结果将返回以下结果:
{
"_id" : ObjectId("55d45c0285afc59c146f66f0"),
"name" : "LG Nexus 6",
"description" : "A Nexus 6 device, created by Google.",
"typenr" : "LG-NEX-5/BLACK",
"props" : [
{
"type" : "os",
"value" : "Android"
},
{
"type" : "storage",
"value" : "8"
},
{
"type" : "storage",
"value" : "16"
},
{
"type" : "storage",
"value" : "32"
},
{
"type" : "storage",
"value" : "64"
}
]
}
// Get all the amount of filters that are defined.
db.smartphones.aggregate([
// Unwind the "props".
{ "$unwind" : "$props" },
// Grouping phase.
// Group by unique properties, add a count for the amount of articles, and add articles to an element named "articles".
// We use the function "$addToSet" here to ensure that only unique articles are being added.
{
"$group" : {
"_id" : "$props",
count : { "$sum" : 1 },
articles: {
"$addToSet": {
name: "$name",
description: "$description",
typenr: "$typenr"
}
}
}
},
// Sort the results based on the "_id" field.
{ "$sort" : { "_id" : 1 } }
]);
"_id" : {
"type" : "storage",
"value" : "128"
},
"count" : 1.0000000000000000,
"articles" : [
{
"name" : "Apple iPhone 6",
"description" : "An iPhone 6 device, created by Apple.",
"typenr" : "APP-IPHONE-6/BLACK"
}
]
// Get all the amount of filters that are defined.
db.smartphones.aggregate([
// Unwind the "props".
{ "$unwind" : "$props" },
// Grouping phase.
// Group by unique properties, add a count for the amount of articles, and add articles to an element named "articles".
// We use the function "$addToSet" here to ensure that only unique articles are being added.
{
"$group" : {
"_id" : "$props",
"count" : { "$sum" : 1 },
"articles" : {
"$addToSet" : {
"name" : "$name",
"description" : "$description",
"typenr" : "$typenr"
}
}
}
},
{ "$sort" : { "_id" : 1 } }
])
var aggregation = collection.Aggregate()
.Unwind<Smartphone, UnwindedSmartphone>(x => x.Properties)
.Group(key => key.Property, g => new
{
Count = g.Count(),
Articles = g.Select(x => new AggregatedSmartphoneArticle
{
Name = x.Name,
Description = x.Description,
Type = x.Type
}).Distinct()
});
现在,在C#中,我用以下方式编写了聚合:
var aggregation = collection.Aggregate()
.Unwind<Smartphone, UnwindedSmartphone>(x => x.Properties)
.Group(key => key.Property, g => new
{
Id = g.Key,
count = g.Count(),
articles = g.Select(x => new
{
name = x.Name,
description = x.Description,
typenr = x.Type
}).Distinct()
})
.SortBy(x => x.Id);
因此,它与我试图转换为C代码的原始聚合相同,只是属性用双引号括起来,但这不是问题
如果我在shell中执行此聚合,结果很好。
但是,在C#中执行时,articles
属性的name
、description
和typenr
具有null
值
有谁知道为什么会这样吗?好的
感谢@BlakesSeven为我指明了正确的方向(见他对我问题的评论,我现在知道我为什么会有这个问题)
我需要转换组中的select
语句
可能不会返回匿名类型。
相反,我需要返回一个类型化对象
这意味着我的代码需要更改为以下内容:
{
"_id" : ObjectId("55d45c0285afc59c146f66f0"),
"name" : "LG Nexus 6",
"description" : "A Nexus 6 device, created by Google.",
"typenr" : "LG-NEX-5/BLACK",
"props" : [
{
"type" : "os",
"value" : "Android"
},
{
"type" : "storage",
"value" : "8"
},
{
"type" : "storage",
"value" : "16"
},
{
"type" : "storage",
"value" : "32"
},
{
"type" : "storage",
"value" : "64"
}
]
}
// Get all the amount of filters that are defined.
db.smartphones.aggregate([
// Unwind the "props".
{ "$unwind" : "$props" },
// Grouping phase.
// Group by unique properties, add a count for the amount of articles, and add articles to an element named "articles".
// We use the function "$addToSet" here to ensure that only unique articles are being added.
{
"$group" : {
"_id" : "$props",
count : { "$sum" : 1 },
articles: {
"$addToSet": {
name: "$name",
description: "$description",
typenr: "$typenr"
}
}
}
},
// Sort the results based on the "_id" field.
{ "$sort" : { "_id" : 1 } }
]);
"_id" : {
"type" : "storage",
"value" : "128"
},
"count" : 1.0000000000000000,
"articles" : [
{
"name" : "Apple iPhone 6",
"description" : "An iPhone 6 device, created by Apple.",
"typenr" : "APP-IPHONE-6/BLACK"
}
]
// Get all the amount of filters that are defined.
db.smartphones.aggregate([
// Unwind the "props".
{ "$unwind" : "$props" },
// Grouping phase.
// Group by unique properties, add a count for the amount of articles, and add articles to an element named "articles".
// We use the function "$addToSet" here to ensure that only unique articles are being added.
{
"$group" : {
"_id" : "$props",
"count" : { "$sum" : 1 },
"articles" : {
"$addToSet" : {
"name" : "$name",
"description" : "$description",
"typenr" : "$typenr"
}
}
}
},
{ "$sort" : { "_id" : 1 } }
])
var aggregation = collection.Aggregate()
.Unwind<Smartphone, UnwindedSmartphone>(x => x.Properties)
.Group(key => key.Property, g => new
{
Count = g.Count(),
Articles = g.Select(x => new AggregatedSmartphoneArticle
{
Name = x.Name,
Description = x.Description,
Type = x.Type
}).Distinct()
});
var aggregation=collection.Aggregate()
.展开(x=>x.Properties)
.Group(key=>key.Property,g=>new
{
Count=g.Count(),
Articles=g.Select(x=>newaggregatedSmartPhoneArticle
{
Name=x.Name,
描述=x.描述,
类型=x.类型
}).Distinct()
});
现在一切正常。
再次感谢。使用键入的代码比使用那些
BsonDocument
要清楚得多,谢谢你的回答,但是什么应该把它们改成我的代码,因为它不太清楚。我看不出我需要在哪里指定输出类型。好吧,我正要在你的“it serializes like this”上调用“phooey”,但你显然刚刚发现你需要给它一个类来用lambda进行迭代。