MongoDB HashTable Averages - PullRequest
       17

MongoDB HashTable Averages

2 голосов
/ 29 мая 2019

Я использую 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 }
  }
}

Предположим, у меня есть объект в коллекции, который выглядит так. Я хотел бы узнать, что можно сделать две вещи.

1: загрузить из базы данных только один элемент из словаря, в настоящее время я могу видеть только, как это можно сделать, загрузив весь запись из базы данных, а затем ручное получение значения по ключу.

2: определить среднее значение одного элемента в базе данных. Например, по всем записям я хотел бы определить среднее стулья, опять же без загрузки всех записей, а затем делать это в памяти с linq и т.д ....

Ответы [ 2 ]

1 голос
/ 29 мая 2019

Обычно ваш образец документа хранится в формате 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:

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

Чтобы получить среднее значение, вам нужно использовать оператор $ toInt , представленный в 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();
0 голосов
/ 30 мая 2019

вот альтернативный способ сделать это, используя MongoDB.Entities вспомогательная библиотека.

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

namespace StackOverflow
{
    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"
            }
        }
    }
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...