Skip to content

Instantly share code, notes, and snippets.

@DejanMilicic
Forked from ayende/Model.cs
Created February 2, 2020 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DejanMilicic/af0e47f4c5cbca32395999bc898ba6b9 to your computer and use it in GitHub Desktop.
Save DejanMilicic/af0e47f4c5cbca32395999bc898ba6b9 to your computer and use it in GitHub Desktop.
Code for lesser known ravendb
using System;
using System.Collections.Generic;
using Raven.Client.Documents.Session.Loaders;
namespace LesserKnownFeatures
{
public class Company
{
public string Id { get; set; }
public string ExternalId { get; set; }
public string Name { get; set; }
public Contact Contact { get; set; }
public Address Address { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public Location Location { get; set; }
}
public class Location
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class Contact
{
public string Name { get; set; }
public string Title { get; set; }
}
public class Category
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Order
{
public string Id { get; set; }
public string Company { get; set; }
public string Employee { get; set; }
public DateTime OrderedAt { get; set; }
public DateTime RequireAt { get; set; }
public DateTime? ShippedAt { get; set; }
public Address ShipTo { get; set; }
public string ShipVia { get; set; }
public decimal Freight { get; set; }
public List<OrderLine> Lines { get; set; }
}
public class OrderLine
{
public string Product { get; set; }
public string ProductName { get; set; }
public decimal PricePerUnit { get; set; }
public int Quantity { get; set; }
public decimal Discount { get; set; }
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Supplier { get; set; }
public string Category { get; set; }
public string QuantityPerUnit { get; set; }
public decimal PricePerUnit { get; set; }
public int UnitsInStock { get; set; }
public int UnitsOnOrder { get; set; }
public bool Discontinued { get; set; }
public int ReorderLevel { get; set; }
}
public class Supplier
{
public string Id { get; set; }
public Contact Contact { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public string HomePage { get; set; }
}
public class Employee
{
public string Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public Address Address { get; set; }
public DateTime HiredAt { get; set; }
public DateTime Birthday { get; set; }
public string HomePhone { get; set; }
public string Extension { get; set; }
public string ReportsTo { get; set; }
public List<string> Notes { get; set; }
public List<string> Territories { get; set; }
}
public class Region
{
public string Id { get; set; }
public string Name { get; set; }
public List<Territory> Territories { get; set; }
}
public class Territory
{
public string Code { get; set; }
public string Name { get; set; }
public string Area { get; set; }
}
public class Shipper
{
public string Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
public class OrdersByCompanyStats
{
public string Company;
public long Count;
public double Total;
}
public class MonthlyBilling
{
public string Company;
public int Year, Month;
public double Amount;
public bool Paid;
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Raven.Client.Documents;
using Raven.Client.Documents.Indexes;
using Raven.Client.Documents.Session;
namespace LesserKnownFeatures
{
class Program
{
static void Main(string[] args)
{
using var store = new DocumentStore
{
Database = "Demo",
Urls = new[] { "http://live-test.ravendb.net/" }
}.Initialize();
using (var s = store.OpenSession())
{
// force connection here
s.Load<Company>("companies/non-there");
}
//RenderCompanyOrders(store, "companies/1-A");
//RenderCompanyOrdersLazy(store, "companies/1-A");
//RenderCompanyOrdersAndSales(store, "companies/1-A");
//for (int i = 0; i < 3; i++)
//{
// RenderCompanyOrders(store, "companies/1-A");
//}
//for (int i = 0; i < 3; i++)
//{
// RenderCompanyOrdersWithCaching(store, "companies/1-A");
//}
//SearchCompany(store);
//PrepareForApiCall(store, "companies/1-A");
//Parallel.For(0, 1000, _ => { DoApiCall(store, "companies/1-A"); });
//StoreTimeSeries();
RecordTimeSeries();
}
private static void StoreTimeSeries()
{
using var store = new DocumentStore
{
Urls = new[] { "http://localhost:8080" },
Database = "Demo"
}.Initialize();
using var session = store.OpenSession();
var timeSeries = session.TimeSeriesFor("nodes/2-A");
var start = DateTime.Today.AddDays(-3);
var random = new Random(1337);
var n1 = 0.4;
var n2 = 0.27;
var n1t = 0;
var n2t = 2;
for (int i = 0; i < 350; i++)
{
var up = random.Next(10) > 5;
for (int j = 0; j < random.Next(7, 18); j++)
{
n1 += random.NextDouble() * (up ? 1 : -1);
if (n1 < 0)
{
n1 = 0;
up = true;
}
timeSeries.Append("DiskQueue",
start.AddSeconds(n1t).AddMilliseconds(150),
"/dev/nvme1",
new[] { n1 }
);
n1t += random.Next(10);
}
for (int j = 0; j < random.Next(7, 18); j++)
{
n2 += random.NextDouble() * (up ? 1 : -1);
if (n2 < 0)
{
n2 = 0;
up = true;
}
timeSeries.Append("DiskQueue",
start.AddSeconds(n1t).AddMilliseconds(250),
"/dev/nvme2",
new[] { n2 }
);
n2t += random.Next(10);
}
}
session.SaveChanges();
}
/*
from Nodes
select
timeseries( from DiskQueue where Tag = '/dev/nvme1' group by 1m select max() ) as OsQ,
timeseries( from DiskQueue where Tag = '/dev/nvme2' group by 1m select max() ) as DatabaseQ
*/
private static void RecordTimeSeries()
{
using var store = new DocumentStore
{
Urls = new[] { "http://localhost:8080" },
Database = "Demo"
}.Initialize();
using var session = store.OpenSession();
var timeSeries = session.TimeSeriesFor("nodes/2-A");
timeSeries.Append("DiskQueue",
DateTime.UtcNow,
"/dev/nvme2",
new[] { 2.4d }
);
session.SaveChanges();
}
private static void PrepareForApiCall(IDocumentStore store, string companyId)
{
using var session = store.OpenSession();
var dateTime = DateTime.UtcNow;
session.Store(new MonthlyBilling
{
Company = companyId,
Month = dateTime.Month,
Year = dateTime.Year,
Amount = 0,
Paid = false
}, $"{companyId}/billing/{dateTime.Year:0000}-{dateTime.Month:00}");
session.SaveChanges();
}
private static void DoApiCall(IDocumentStore store, string companyId)
{
using var session = store.OpenSession();
var dateTime = DateTime.UtcNow;
session.Store(new Order
{
Company = companyId,
// other details here
});
var counters = session.CountersFor($"{companyId}/billing/{dateTime.Year:0000}-{dateTime.Month:00}");
counters.Increment(dateTime.ToString("dd-hh:mm"), 1);
session.SaveChanges();
/*
// compute total charge for a month
from MonthlyBillings as b
where b.Company = 'companies/1-A' and b.Charged = false
select {
Total: getMetadata(b)['@counters']
.reduce((sum, cur) => counter(b, cur) + sum, 0)
}
*/
}
public class Companies_Search : AbstractIndexCreationTask<Company, Companies_Search.Item>
{
public class Item
{
public string Query;
}
public Companies_Search()
{
Map = companies =>
from company in companies
select new
{
Query = new[]
{
company.Name,
company.ExternalId,
company.Contact.Name,
}
};
Index(i => i.Query, FieldIndexing.Search);
Suggestion(i => i.Query);
}
}
public static void SearchCompany(IDocumentStore store)
{
//new Companies_Search().Execute(store);
while (true)
{
Console.WriteLine("What are you looking for?");
var term = Console.ReadLine();
using var session = store.OpenSession();
var companies = session.Query<Companies_Search.Item, Companies_Search>()
.Search(x => x.Query, term)
.OfType<Company>()
.ToList();
if (companies.Count != 0)
{
foreach (var company in companies)
{
Console.WriteLine(company.Name);
}
}
else
{
var results = session.Query<Companies_Search.Item, Companies_Search>()
.SuggestUsing(x => x.ByField(i => i.Query, term))
.Execute();
if (results.Count > 0)
{
Console.WriteLine("Did you mean?");
foreach (var r in results.Values)
{
Console.WriteLine(string.Join(", ", r.Suggestions));
}
}
else
{
Console.WriteLine("Couldn't find anything, try again?");
}
}
}
}
private static void RenderCompanyOrdersAndSales(IDocumentStore store, string companyId)
{
var sp = Stopwatch.StartNew();
using var session = store.OpenSession();
var stats = session.Query<OrdersByCompanyStats>("Orders/ByCompany")
.Include(x => x.Company)
.Where(x => x.Company == companyId)
.Lazily();
var recentOrders = session.Query<Order>()
.Include(o => o.Lines.Select(l => l.Product))
.Where(x => x.Company == companyId)
.OrderBy(x => x.OrderedAt)
.Take(5)
.Lazily();
session.Advanced.Eagerly.ExecuteAllPendingLazyOperations();
var company = session.Load<Company>(companyId);
sp.Stop();
foreach (var stat in stats.Value)
{
Console.WriteLine($"Sales: {stat.Count} Value: {stat.Total:C}");
}
PrintCustomerPage(session, company, recentOrders.Value.ToList(), sp);
}
private static void RenderCompanyOrdersWithCaching(IDocumentStore store, string companyId)
{
var sp = Stopwatch.StartNew();
using var _ = store.AggressivelyCache();
using var session = store.OpenSession();
var stats = session.Query<OrdersByCompanyStats>("Orders/ByCompany")
.Include(x => x.Company)
.Where(x => x.Company == companyId)
.Lazily();
var recentOrders = session.Query<Order>()
.Include(o => o.Lines.Select(l => l.Product))
.Where(x => x.Company == companyId)
.OrderBy(x => x.OrderedAt)
.Take(5)
.Lazily();
var company = session.Load<Company>(companyId);
sp.Stop();
foreach (var stat in stats.Value)
{
Console.WriteLine($"Sales: {stat.Count} Value: {stat.Total:C}");
}
PrintCustomerPage(session, company, recentOrders.Value.ToList(), sp);
}
private static void RenderCompanyOrders(IDocumentStore store, string companyId)
{
var sp = Stopwatch.StartNew();
using var session = store.OpenSession();
var company = session.Load<Company>(companyId);
var queryable = session.Query<Order>()
.Include(x => x.Lines.Select(y => y.Product))
.Where(x => x.Company == companyId)
.OrderBy(x => x.OrderedAt)
.Take(5);
var recentOrders = queryable
.ToList();
PrintCustomerPage(session, company, recentOrders, sp);
}
private static void RenderCompanyOrdersLazy(IDocumentStore store, string companyId)
{
var sp = Stopwatch.StartNew();
using var session = store.OpenSession();
Lazy<Company> company = session.Advanced.Lazily.Load<Company>(companyId);
Lazy<IEnumerable<Order>> recentOrders = session.Query<Order>()
.Include(o => o.Lines.Select(l => l.Product))
.Where(x => x.Company == companyId)
.OrderBy(x => x.OrderedAt)
.Take(5)
.Lazily();
session.Advanced.Eagerly.ExecuteAllPendingLazyOperations();
PrintCustomerPage(session, company.Value, recentOrders.Value.ToList(), sp);
}
private static void PrintCustomerPage(IDocumentSession session, Company company, List<Order> recentOrders, Stopwatch sw)
{
//var recentProducts = new Dictionary<string, Product>();
//foreach (var order in recentOrders)
//{
// foreach (var orderLine in order.Lines)
// {
// if (recentProducts.TryGetValue(orderLine.Product, out _) == false)
// {
// recentProducts[orderLine.Product] = session.Load<Product>(orderLine.Product);
// }
// }
//}
var recentProducts = recentOrders
.SelectMany(o => o.Lines.Select(l => l.Product))
.Distinct()
.Select(session.Load<Product>);
Console.WriteLine(company.Name);
Console.WriteLine("- - - - - - - - -");
Console.WriteLine("Orders:");
foreach (var o in recentOrders)
{
Console.WriteLine($"\t{o.Id} {o.Lines.Sum(x => x.PricePerUnit * x.Quantity)} {o.OrderedAt}");
}
Console.WriteLine("- - - - - - - - -");
Console.WriteLine("Products to order again?");
foreach (var p in recentProducts)
{
Console.WriteLine($"\t{p.Name}");
}
Console.WriteLine("- - - - - - - - -");
Console.WriteLine($"{session.Advanced.NumberOfRequests} requests to the server in {sw.ElapsedMilliseconds:#,#} ms");
Console.WriteLine(Rhino);
}
private const string Rhino = @" _ __
__.--**""""""**--...__..--**""""""""*-.
.' `-.
.' _ \
/ .' . \ _._
: : :`*. :-'.' ;
; ` ; `.) \ /.-'
: ` ; ' -* ;
:. \ : : : :
; ; `. `. ; ` | '
| `. `. -*""*\; / :
| : /`-. `. \/`.' _ `.
: ; : `*-.__.-*"""""":`. \ ; 'o` `. /
; ; ; \ ;: ;: ,/
| | | /` | , `*-*'/
` : : : / / | : . ._.-'
\ \ , \ : `. : \ \ .'
: *: ; : |`*-' `*+-*
`**-*`"""" *---*";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment