Ejemplo n.º 1
0
        public void IncludeTimeSeriesAndUpdateExistingRangeInCache_Typed()
        {
            using (var store = GetDocumentStore())
            {
                var baseline = RavenTestHelper.UtcToday;

                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "Oren"
                    }, "users/ayende");
                    session.SaveChanges();
                }

                using (var session = store.OpenSession())
                {
                    var tsf = session.TimeSeriesFor <HeartRateMeasure>("users/ayende");
                    for (int i = 0; i < 360; i++)
                    {
                        var typedMeasure = new HeartRateMeasure
                        {
                            HeartRate = 6
                        };
                        tsf.Append(baseline.AddSeconds(i * 10), typedMeasure, "watches/fitbit");
                    }

                    session.SaveChanges();
                }

                using (var session = store.OpenSession())
                {
                    var vals = session.TimeSeriesFor <HeartRateMeasure>("users/ayende")
                               .Get(baseline.AddMinutes(2), baseline.AddMinutes(10))
                               .ToList();

                    Assert.Equal(1, session.Advanced.NumberOfRequests);

                    Assert.Equal(49, vals.Count);
                    Assert.Equal(baseline.AddMinutes(2), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(10), vals[48].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    session.TimeSeriesFor <HeartRateMeasure>("users/ayende")
                    .Append(baseline.AddMinutes(3).AddSeconds(3), new HeartRateMeasure
                    {
                        HeartRate = 6
                    }, "watches/fitbit");
                    session.SaveChanges();

                    Assert.Equal(2, session.Advanced.NumberOfRequests);

                    var user = session.Load <User>(
                        "users/ayende",
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline.AddMinutes(3), baseline.AddMinutes(5)));

                    Assert.Equal(3, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>("users/ayende")
                           .Get(baseline.AddMinutes(3), baseline.AddMinutes(5))
                           .ToList();

                    Assert.Equal(3, session.Advanced.NumberOfRequests);

                    Assert.Equal(14, vals.Count);
                    Assert.Equal(baseline.AddMinutes(3), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(3).AddSeconds(3), vals[1].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(5), vals[13].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                }
            }
        }
Ejemplo n.º 2
0
        public void CanQueryTimeSeriesAggregation_NoSelectOrGroupBy()
        {
            using (var store = GetDocumentStore())
            {
                var baseline = RavenTestHelper.UtcToday;

                using (var session = store.OpenSession())
                {
                    for (int i = 1; i <= 3; i++)
                    {
                        var id = $"people/{i}";

                        session.Store(new User
                        {
                            Name = "Oren",
                            Age  = i * 30
                        }, id);

                        var tsf = session.TimeSeriesFor <HeartRateMeasure>(id);
                        var m   = new HeartRateMeasure
                        {
                            HeartRate = 59d,
                        };

                        tsf.Append(baseline.AddMinutes(61), m, "watches/fitbit");

                        m.HeartRate = 79d;
                        tsf.Append(baseline.AddMinutes(62), m, "watches/fitbit");

                        m.HeartRate = 69d;
                        tsf.Append(baseline.AddMinutes(63), m, "watches/apple");

                        m.HeartRate = 159d;
                        tsf.Append(baseline.AddMonths(1).AddMinutes(61), m, "watches/fitbit");

                        m.HeartRate = 179d;
                        tsf.Append(baseline.AddMonths(1).AddMinutes(62), m, "watches/apple");

                        m.HeartRate = 169d;
                        tsf.Append(baseline.AddMonths(1).AddMinutes(63), m, "watches/fitbit");
                    }

                    session.SaveChanges();
                }

                using (var session = store.OpenSession())
                {
                    var query = session.Advanced.RawQuery <TimeSeriesRawResult <HeartRateMeasure> >(@"
declare timeseries out(x)
{
    from x.HeartRateMeasures between $start and $end
}
from Users as doc
where doc.Age > 49
select out(doc)
")
                                .AddParameter("start", baseline.EnsureUtc())
                                .AddParameter("end", baseline.AddMonths(2).EnsureUtc());

                    var result = query.ToList();

                    Assert.Equal(2, result.Count);

                    for (int i = 0; i < 2; i++)
                    {
                        var agg = result[i];

                        Assert.Equal(6, agg.Results.Length);

                        var val = agg.Results[0];

                        Assert.Equal(1, val.Values.Length);
                        Assert.Equal(59, val.Value.HeartRate);
                        Assert.Equal("watches/fitbit", val.Tag);
                        Assert.Equal(baseline.AddMinutes(61), val.Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                        val = agg.Results[1];
                        Assert.Equal(1, val.Values.Length);
                        Assert.Equal(79, val.Value.HeartRate);
                        Assert.Equal("watches/fitbit", val.Tag);
                        Assert.Equal(baseline.AddMinutes(62), val.Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                        val = agg.Results[2];

                        Assert.Equal(1, val.Values.Length);
                        Assert.Equal(69, val.Value.HeartRate);
                        Assert.Equal("watches/apple", val.Tag);
                        Assert.Equal(baseline.AddMinutes(63), val.Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                        val = agg.Results[3];

                        Assert.Equal(1, val.Values.Length);
                        Assert.Equal(159, val.Value.HeartRate);
                        Assert.Equal("watches/fitbit", val.Tag);
                        Assert.Equal(baseline.AddMonths(1).AddMinutes(61), val.Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                        val = agg.Results[4];

                        Assert.Equal(1, val.Values.Length);
                        Assert.Equal(179, val.Value.HeartRate);
                        Assert.Equal("watches/apple", val.Tag);
                        Assert.Equal(baseline.AddMonths(1).AddMinutes(62), val.Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                        val = agg.Results[5];

                        Assert.Equal(1, val.Values.Length);
                        Assert.Equal(169, val.Value.HeartRate);
                        Assert.Equal("watches/fitbit", val.Tag);
                        Assert.Equal(baseline.AddMonths(1).AddMinutes(63), val.Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public void IncludeTimeSeriesAndMergeWithExistingRangesInCache_Typed()
        {
            using (var store = GetDocumentStore())
            {
                var baseline = RavenTestHelper.UtcToday;

                var documentId = "users/ayende";

                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "Oren"
                    }, documentId);
                    session.SaveChanges();
                }

                using (var session = store.OpenSession())
                {
                    var tsf = session.TimeSeriesFor <HeartRateMeasure>(documentId);
                    for (int i = 0; i < 360; i++)
                    {
                        var typedMeasure = new HeartRateMeasure
                        {
                            HeartRate = 6
                        };
                        tsf.Append(baseline.AddSeconds(i * 10), typedMeasure, "watches/fitbit");
                    }

                    session.SaveChanges();
                }

                using (var session = store.OpenSession())
                {
                    var vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                               .Get(baseline.AddMinutes(2), baseline.AddMinutes(10))
                               .ToList();

                    Assert.Equal(1, session.Advanced.NumberOfRequests);

                    Assert.Equal(49, vals.Count);
                    Assert.Equal(baseline.AddMinutes(2), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(10), vals[48].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    var user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline.AddMinutes(40), baseline.AddMinutes(50)));

                    Assert.Equal(2, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline.AddMinutes(40), baseline.AddMinutes(50))
                           .ToList();

                    Assert.Equal(2, session.Advanced.NumberOfRequests);

                    Assert.Equal(61, vals.Count);
                    Assert.Equal(baseline.AddMinutes(40), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), vals[60].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    var sessionOperations = (InMemoryDocumentSessionOperations)session;

                    Assert.True(sessionOperations.TimeSeriesByDocId.TryGetValue(documentId, out var cache));
                    Assert.True(cache.TryGetValue("HeartRateMeasures", out var ranges));
                    Assert.Equal(2, ranges.Count);

                    Assert.Equal(baseline.AddMinutes(2), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(10), ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(40), ranges[1].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), ranges[1].To, RavenTestHelper.DateTimeComparer.Instance);

                    // we intentionally evict just the document (without it's TS data),
                    // so that Load request will go to server

                    sessionOperations.DocumentsByEntity.Evict(user);
                    sessionOperations.DocumentsById.Remove(documentId);

                    // should go to server to get [0, 2] and merge it into existing [2, 10]
                    user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline, baseline.AddMinutes(2)));

                    Assert.Equal(3, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline, baseline.AddMinutes(2))
                           .ToList();

                    Assert.Equal(3, session.Advanced.NumberOfRequests);

                    Assert.Equal(13, vals.Count);
                    Assert.Equal(baseline, vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(2), vals[12].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    Assert.Equal(2, ranges.Count);
                    Assert.Equal(baseline.AddMinutes(0), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(10), ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(40), ranges[1].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), ranges[1].To, RavenTestHelper.DateTimeComparer.Instance);

                    // evict just the document
                    sessionOperations.DocumentsByEntity.Evict(user);
                    sessionOperations.DocumentsById.Remove(documentId);

                    // should go to server to get [10, 16] and merge it into existing [0, 10]
                    user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline.AddMinutes(10), baseline.AddMinutes(16)));

                    Assert.Equal(4, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline.AddMinutes(10), baseline.AddMinutes(16))
                           .ToList();

                    Assert.Equal(4, session.Advanced.NumberOfRequests);

                    Assert.Equal(37, vals.Count);
                    Assert.Equal(baseline.AddMinutes(10), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(16), vals[36].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    Assert.Equal(2, ranges.Count);
                    Assert.Equal(baseline.AddMinutes(0), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(16), ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(40), ranges[1].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), ranges[1].To, RavenTestHelper.DateTimeComparer.Instance);

                    // evict just the document
                    sessionOperations.DocumentsByEntity.Evict(user);
                    sessionOperations.DocumentsById.Remove(documentId);

                    // should go to server to get range [17, 19]
                    // and add it to cache in between [10, 16] and [40, 50]

                    user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline.AddMinutes(17), baseline.AddMinutes(19)));

                    Assert.Equal(5, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline.AddMinutes(17), baseline.AddMinutes(19))
                           .ToList();

                    Assert.Equal(5, session.Advanced.NumberOfRequests);

                    Assert.Equal(13, vals.Count);
                    Assert.Equal(baseline.AddMinutes(17), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(19), vals[12].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    Assert.Equal(3, ranges.Count);
                    Assert.Equal(baseline.AddMinutes(0), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(16), ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(17), ranges[1].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(19), ranges[1].To, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(40), ranges[2].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), ranges[2].To, RavenTestHelper.DateTimeComparer.Instance);

                    // evict just the document
                    sessionOperations.DocumentsByEntity.Evict(user);
                    sessionOperations.DocumentsById.Remove(documentId);

                    // should go to server to get range [19, 40]
                    // and merge the result with existing ranges [17, 19] and [40, 50]
                    // into single range [17, 50]

                    user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline.AddMinutes(18), baseline.AddMinutes(48)));

                    Assert.Equal(6, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline.AddMinutes(18), baseline.AddMinutes(48))
                           .ToList();

                    Assert.Equal(6, session.Advanced.NumberOfRequests);

                    Assert.Equal(181, vals.Count);
                    Assert.Equal(baseline.AddMinutes(18), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(48), vals[180].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    Assert.Equal(2, ranges.Count);
                    Assert.Equal(baseline.AddMinutes(0), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(16), ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(17), ranges[1].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), ranges[1].To, RavenTestHelper.DateTimeComparer.Instance);

                    // evict just the document
                    sessionOperations.DocumentsByEntity.Evict(user);
                    sessionOperations.DocumentsById.Remove(documentId);

                    // should go to server to get range [12, 22]
                    // and merge the result with existing ranges [0, 16] and [17, 50]
                    // into single range [0, 50]

                    user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", baseline.AddMinutes(12), baseline.AddMinutes(22)));

                    Assert.Equal(7, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline.AddMinutes(12), baseline.AddMinutes(22))
                           .ToList();

                    Assert.Equal(7, session.Advanced.NumberOfRequests);

                    Assert.Equal(61, vals.Count);
                    Assert.Equal(baseline.AddMinutes(12), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(22), vals[60].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    Assert.Equal(1, ranges.Count);
                    Assert.Equal(baseline.AddMinutes(0), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(50), ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);

                    // evict just the document
                    sessionOperations.DocumentsByEntity.Evict(user);
                    sessionOperations.DocumentsById.Remove(documentId);

                    // should go to server to get range [50, ∞]
                    // and merge the result with existing range [0, 50] into single range [0, ∞]

                    user = session.Load <User>(
                        documentId,
                        i => i.IncludeTimeSeries("HeartRateMeasures", TimeSeriesRangeType.Last, TimeValue.FromMinutes(10)));

                    Assert.Equal(8, session.Advanced.NumberOfRequests);

                    // should not go to server

                    vals = session.TimeSeriesFor <HeartRateMeasure>(documentId)
                           .Get(baseline.AddMinutes(50))
                           .ToList();

                    Assert.Equal(8, session.Advanced.NumberOfRequests);

                    Assert.Equal(60, vals.Count);
                    Assert.Equal(baseline.AddMinutes(50), vals[0].Timestamp, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(59).AddSeconds(50), vals[59].Timestamp, RavenTestHelper.DateTimeComparer.Instance);

                    Assert.Equal(1, ranges.Count);
                    Assert.Equal(baseline.AddMinutes(0), ranges[0].From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(DateTime.MaxValue, ranges[0].To, RavenTestHelper.DateTimeComparer.Instance);
                }
            }
        }
Ejemplo n.º 4
0
        public unsafe void CanQueryTimeSeriesAggregation_DeclareSyntax_AllDocsQuery()
        {
            using (var store = GetDocumentStore())
            {
                var baseline = RavenTestHelper.UtcToday;

                using (var session = store.OpenSession())
                {
                    session.Store(new { Name = "Oren" }, "users/ayende");

                    var tsf = session.TimeSeriesFor <HeartRateMeasure>("users/ayende");
                    var tag = "watches/fitbit";
                    var m   = new HeartRateMeasure
                    {
                        HeartRate = 59d,
                    };
                    tsf.Append(baseline.AddMinutes(61), m, tag);

                    m.HeartRate = 79d;
                    tsf.Append(baseline.AddMinutes(62), m, tag);

                    m.HeartRate = 69d;
                    tsf.Append(baseline.AddMinutes(63), m, tag);

                    session.SaveChanges();
                }

                using (var session = store.OpenSession())
                {
                    var query = session.Advanced.RawQuery <TimeSeriesAggregationResult <HeartRateMeasure> >(@"
    declare timeseries out(u)
    {
        from u.HeartRateMeasures between $start and $end
        group by 1h
        select min(), max(), first(), last()
    }
    from @all_docs as u
    where id() == 'users/ayende'
    select out(u)
")
                                .AddParameter("start", baseline.EnsureUtc())
                                .AddParameter("end", baseline.AddDays(1).EnsureUtc());

                    var agg = query.First();
                    if (agg.Count != 3)
                    {
                        var db  = Databases.GetDocumentDatabaseInstanceFor(store).Result;
                        var tss = db.DocumentsStorage.TimeSeriesStorage;
                        using (db.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx))
                            using (ctx.OpenReadTransaction())
                            {
                                var reader = tss.GetReader(ctx, "users/ayende", nameof(HeartRateMeasure) + "s", baseline, baseline.AddDays(1));

                                Assert.True(reader.Init());

                                Assert.NotNull(reader._tvr);

                                var key = reader._tvr.Read(0, out var size);

                                TimeSeriesValuesSegment.ParseTimeSeriesKey(key, size, ctx, out var docId, out var name, out DateTime baseline2);

                                Assert.Equal("users/ayende", docId);
                                Assert.Equal(nameof(HeartRateMeasure) + "s", name, StringComparer.InvariantCultureIgnoreCase);
                                Assert.Equal(baseline.AddMinutes(61), baseline2, RavenTestHelper.DateTimeComparer.Instance);

                                Assert.Equal(1, reader.SegmentsOrValues().Count());

                                Assert.False(query.First().Count == 3, "Query assertion failed once and passed on second try. sanity check passed");

                                //Assert.True(false, "Query assertion failed twice. sanity check passed");
                            }
                    }

                    Assert.Equal(3, agg.Count);

                    Assert.Equal(1, agg.Results.Length);

                    var val = agg.Results[0];
                    Assert.Equal(59, val.First.HeartRate);
                    Assert.Equal(59, val.Min.HeartRate);

                    Assert.Equal(69, val.Last.HeartRate);
                    Assert.Equal(79, val.Max.HeartRate);

                    Assert.Equal(baseline.AddMinutes(60), val.From, RavenTestHelper.DateTimeComparer.Instance);
                    Assert.Equal(baseline.AddMinutes(120), val.To, RavenTestHelper.DateTimeComparer.Instance);
                }
            }
        }