C# MongoDB哈希表平均值

C# MongoDB哈希表平均值,c#,mongodb,mongodb-query,mongodb-.net-driver,C#,Mongodb,Mongodb Query,Mongodb .net Driver,我正在使用c#,以及MongoDB。 我有一门课,可以用这个来形容。 这是一个例子,代表了一些东西,请不要评论课堂设计 [CollectionName("Venues")] public class Venue { public string Name { get; set; } public dictionary<string,object> Properties { get; set; } } var venue = new Venue { Name = "Ve

我正在使用c#,以及MongoDB。 我有一门课,可以用这个来形容。 这是一个例子,代表了一些东西,请不要评论课堂设计

[CollectionName("Venues")]
public class Venue
{
   public string Name { get; set; }
   public dictionary<string,object> Properties { get; set; }
}

var venue = new Venue
{
  Name = "Venue 1",
  Properties = new Dictionary<string,object>
  {
    { "Chairs", "18" },
    { "Tables", "4" },
    { "HasWaterfall", true }
  }
}
[CollectionName(“场馆”)]
公共课堂场地
{
公共字符串名称{get;set;}
公共字典属性{get;set;}
}
var场馆=新场馆
{
Name=“场馆1”,
属性=新字典
{
{“椅子”,“18”},
{“表”,“4”},
{“瀑布”,真的}
}
}
假设集合中有一个对象,看起来是这样的。 我想找出有可能做的两件事

1:从数据库加载,仅从字典中加载一项, 目前,我只能通过加载整个 从数据库中记录,然后通过键手动获取值

2:确定数据库中单个项目的平均值。 例如,我想计算所有记录的平均值 椅子,再次不加载所有记录,然后在内存中使用
linq等…

基本上,您的示例文档存储为以下JSON格式:

{
    "_id" : ObjectId("..."),
    "Name" : "Venue 1",
    "Properties" : {
            "Chairs" : "18",
            "Tables" : "4",
            "HasWaterfall" : true
    }
}
这使您可以使用点符号定义投影:

var filter = Builders<Venue>.Filter.Eq(f => f.Name, "Venue 1");
var projection = Builders<Venue>.Projection.Include("Properties.Chairs");

List<BsonDocument> data = Col.Find(filter).Project(projection).ToList();
要获得平均值,需要使用MongoDB 4.0中引入的运算符将值从字符串转换为int。请尝试:

var project = new BsonDocument()
{
    { "chairs", new BsonDocument() { { "$toInt", "$Properties.Chairs" } } }
};

var group = new BsonDocument()
{
    { "_id", "null" },
    { "avg", new BsonDocument() { { "$avg", "$chairs" }  } }
};

var avg = Col.Aggregate().Project(project).Group(group).First();

这里有一种使用便利库的替代方法

使用System.Collections.Generic;
使用System.Linq;
使用MongoDB.Entities;
命名空间堆栈溢出
{
班级计划
{
[名称(“场馆”)]
公共课堂地点:实体
{
公共字符串名称{get;set;}
公共字典属性{get;set;}
}
静态void Main(字符串[]参数)
{
新DB(“测试”);
var venue1=新场地
{
Name=“场馆1”,
属性=新字典{
{“椅子”,28},
{“表格”,4},
{“瀑布”,真的}
}
};
venue1.Save();
var venue2=新场地
{
Name=“场馆2”,
属性=新字典{
{“椅子”,38},
{“表格”,4},
{“瀑布”,真的}
}
};
venue2.Save();
var=DB.Find()
.Match(v=>v.Name==“场馆1”)
.Project(v=>new{ChairCount=v.Properties[“Chairs”]})
.Execute();
var avgChairs=DB.Collection()
.平均(v=>(int)v.属性[“椅子]);
}
}
}
导致对数据库进行以下查询:

在场馆1获得椅子:

db.runCommand({
“查找”:“场地”,
“过滤器”:{
“名称”:“场馆1”
},
“投影”:{
“财产.椅子”:数字印刷(“1”),
“\u id”:数字打印(“0”)
},
$db:“测试”
})
获得所有场馆的平均椅子数量:

db.victions.aggregate([
{
“$group”:{
“_id”:数字印刷(“1”),
“_结果”:{
“$avg”:“$Properties.Chairs”
}
}
}
])

精彩的回答和解释,谢谢。我看到它在v4上工作得很好,我仅限于V3.6,Azure Cosmos DB,但我将尝试为$toInt找到另一个不存在的实现。还有一个很好的答案。
var project = new BsonDocument()
{
    { "chairs", new BsonDocument() { { "$toInt", "$Properties.Chairs" } } }
};

var group = new BsonDocument()
{
    { "_id", "null" },
    { "avg", new BsonDocument() { { "$avg", "$chairs" }  } }
};

var avg = Col.Aggregate().Project(project).Group(group).First();