-
-
Save DejanMilicic/af0e47f4c5cbca32395999bc898ba6b9 to your computer and use it in GitHub Desktop.
Code for lesser known ravendb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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