MongoDB 哈希表平均值

MongoDB HashTable Averages

我正在使用 c#,以及 MongoDB。 我有一个 class 可以与此类似。 它是一个示例,代表了一些东西,请不要评论 class 设计

[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 }
  }
}

假设我在集合中有一个对象,看起来像这样。 我想找出有可能做两件事。

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

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();

BsonDocument 下面的 returns:

{ "_id" : ObjectId("..."), "Properties" : { "Chairs" : "18" } }

要获得平均值,您需要使用 MongoDB 4.0 中引入的 $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();

这是使用 MongoDB.Entities 便利库的另一种方法。

using System.Collections.Generic;
using System.Linq;
using MongoDB.Entities;

namespace Whosebug
{
    class Program
    {
        [Name("Venues")]
        public class Venue : Entity
        {
            public string Name { get; set; }
            public Dictionary<string, object> Properties { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            var venue1 = new Venue
            {
                Name = "Venue 1",
                Properties = new Dictionary<string, object>  {
                    { "Chairs", 28 },
                    { "Tables", 4 },
                    { "HasWaterfall", true }
                }
            };
            venue1.Save();

            var venue2 = new Venue
            {
                Name = "Venue 2",
                Properties = new Dictionary<string, object>  {
                    { "Chairs", 38 },
                    { "Tables", 4 },
                    { "HasWaterfall", true }
                }
            };
            venue2.Save();

            var chairs = DB.Find<Venue, object>()
                           .Match(v => v.Name == "Venue 1")
                           .Project(v => new { ChairCount = v.Properties["Chairs"] })
                           .Execute();

            var avgChairs = DB.Collection<Venue>()
                              .Average(v => (int)v.Properties["Chairs"]);

        }
    }
}

导致对数据库进行以下查询:

在场地 1 拿椅子:

db.runCommand({
    "find": "Venues",
    "filter": {
        "Name": "Venue 1"
    },
    "projection": {
        "Properties.Chairs": NumberInt("1"),
        "_id": NumberInt("0")
    },
    "$db": "test"
})

获取所有场馆的平均椅子数:

db.Venues.aggregate([
    {
        "$group": {
            "_id": NumberInt("1"),
            "__result": {
                "$avg": "$Properties.Chairs"
            }
        }
    }
])