public void TestPredictiveIndexOnValues() { CreateDocument(1, 2, 3, 4, 5); CreateDocument(6, 7, 8, 9, 10); var aggregateModel = new AggregateModel(); aggregateModel.RegisterModel(); var model = nameof(AggregateModel); var input = AggregateModel.CreateInput("numbers"); var prediction = Function.Prediction(model, input); var index = IndexBuilder.PredictiveIndex(model, input, "sum"); Db.CreateIndex("SumIndex", index); aggregateModel.AllowCalls = false; using (var q = QueryBuilder.Select(SelectResult.Property("numbers"), SelectResult.Expression(prediction.Property("sum")).As("sum")) .From(DataSource.Database(Db)) .Where(prediction.Property("sum").EqualTo(Expression.Int(15)))) { var explain = q.Explain(); explain.Contains("USING INDEX SumIndex").Should().BeTrue(); var rows = VerifyQuery(q, (n, result) => { result.GetInt(1).Should().Be(15); }); aggregateModel.Error.Should().BeNull(); rows.Should().Be(1); aggregateModel.NumberOfCalls.Should().Be(2); } }
public void TestValueIndexMultipleValues() { CreateDocument(1, 2, 3, 4, 5); CreateDocument(6, 7, 8, 9, 10); var aggregateModel = new AggregateModel(); aggregateModel.RegisterModel(); var input = AggregateModel.CreateInput("numbers"); var sumPrediction = Function.Prediction(aggregateModel.Name, input).Property("sum"); var avgPrediction = Function.Prediction(aggregateModel.Name, input).Property("avg"); var sumIndex = IndexBuilder.ValueIndex(ValueIndexItem.Expression(sumPrediction)); Db.CreateIndex("SumIndex", sumIndex); var avgIndex = IndexBuilder.ValueIndex(ValueIndexItem.Expression(avgPrediction)); Db.CreateIndex("AvgIndex", avgIndex); using (var q = QueryBuilder.Select(SelectResult.Expression(sumPrediction).As("s"), SelectResult.Expression(avgPrediction).As("a")) .From(DataSource.Database(Db)) .Where(sumPrediction.LessThanOrEqualTo(Expression.Int(15)).Or(avgPrediction.EqualTo(Expression.Int(8))))) { var explain = q.Explain(); explain.IndexOf("USING INDEX SumIndex").Should().NotBe(-1, "because the sum index should be used"); explain.IndexOf("USING INDEX AvgIndex").Should().NotBe(-1, "because the average index should be used"); var numRows = VerifyQuery(q, (n, r) => { r.Should().Match <Result>(x => x.GetLong(0) == 15 || x.GetLong(1) == 8); }); numRows.Should().Be(2); } }
public void TestCreateIndex() { Db.GetIndexes().Should().BeEmpty(); var fName = Expression.Property("firstName"); var lName = Expression.Property("lastName"); var fNameItem = ValueIndexItem.Property("firstName"); var lNameItem = ValueIndexItem.Expression(lName); var index1 = IndexBuilder.ValueIndex(fNameItem, lNameItem); Db.CreateIndex("index1", index1); var detailItem = FullTextIndexItem.Property("detail"); var index2 = IndexBuilder.FullTextIndex(detailItem); Db.CreateIndex("index2", index2); var detailItem2 = FullTextIndexItem.Property("es-detail"); var index3 = IndexBuilder.FullTextIndex(detailItem2).IgnoreAccents(true).SetLanguage("es"); Db.CreateIndex("index3", index3); Db.GetIndexes().ShouldBeEquivalentTo(new[] { "index1", "index2", "index3" }); }
public void TestValueIndex() { CreateDocument(1, 2, 3, 4, 5); CreateDocument(6, 7, 8, 9, 10); var aggregateModel = new AggregateModel(); aggregateModel.RegisterModel(); var input = AggregateModel.CreateInput("numbers"); var sumPrediction = Function.Prediction(aggregateModel.Name, input).Property("sum"); var index = IndexBuilder.ValueIndex(ValueIndexItem.Expression(sumPrediction)); Db.CreateIndex("SumIndex", index); using (var q = QueryBuilder.Select(SelectResult.Property("numbers"), SelectResult.Expression(sumPrediction)) .From(DataSource.Database(Db)) .Where(sumPrediction.EqualTo(Expression.Int(15)))) { q.Explain().IndexOf("USING INDEX SumIndex").Should() .NotBe(-1, "because the query should make use of the index"); var numRows = VerifyQuery(q, (n, r) => { var numbers = r.GetArray(0).Cast <long>().ToList(); var sum = r.GetLong(1); sum.Should().Be(numbers.Sum()); }); numRows.Should().Be(1); aggregateModel.NumberOfCalls.Should().Be(2, "because the value should be cached and not call the prediction function again"); } }
private int FullTextSearch() { _indexFTSBench.Start(); var nameExpr = Expression.Property("Name"); var index = Index.FullTextIndex().On(FullTextIndexItem.Expression(nameExpr)); Db.CreateIndex("nameFTS", index); _indexFTSBench.Stop(); var ARTIST = Expression.Property("Artist"); var ALBUM = Expression.Property("Album"); var NAME = Expression.Property("Name"); var results = new List <string>(); using (var q = Query.Select(SelectResult.Expression(ARTIST), SelectResult.Expression(ALBUM), SelectResult.Expression(NAME)) .From(DataSource.Database(Db)) .Where(NAME.Match("'Rock'")) .OrderBy(Ordering.Property("Artist"), Ordering.Property("Album"))) { _queryFTSBench.Start(); using (var rows = q.Execute()) { foreach (var row in rows) { results.Add(row.GetString(2)); } } } _queryFTSBench.Stop(); results.Count.Should().Be(30); return(results.Count); }
public void TestCreateSameIndexTwice() { var item = ValueIndexItem.Expression(Expression.Property("firstName")); var index = IndexBuilder.ValueIndex(item); Db.CreateIndex("myindex", index); Db.CreateIndex("myindex", index); Db.GetIndexes().ShouldBeEquivalentTo(new[] { "myindex" }); }
private void CreateArtistsIndex() { _indexArtistsBench.Start(); var collation = Collation.Unicode().IgnoreCase(true).IgnoreAccents(true); var artist = Expression.Property("Artist").Collate(collation); var comp = Expression.Property("Compilation"); var index = Index.ValueIndex().On(ValueIndexItem.Expression(artist), ValueIndexItem.Expression(comp)); Db.CreateIndex("byArtist", index); _indexArtistsBench.Stop(); }
public void TestConcurrentCreateNCreateIndexDB() { const int nDocs = 1000; var exp1 = new WaitAssert(); var ignore = exp1.RunAssertAsync(() => { CreateDocs(nDocs, "Create").ToList(); }); Db.CreateIndex("sentence", IndexBuilder.FullTextIndex(FullTextIndexItem.Property("sentence"))); exp1.WaitForResult(TimeSpan.FromSeconds(60)); }
public void TestValueIndexCompoundValues() { CreateDocument(1, 2, 3, 4, 5); CreateDocument(6, 7, 8, 9, 10); var aggregateModel = new AggregateModel(); aggregateModel.RegisterModel(); var input = Expression.Dictionary(new Dictionary <string, object> { ["numbers"] = Expression.Property("numbers") }); var sumPrediction = Function.Prediction(aggregateModel.Name, input).Property("sum"); var avgPrediction = Function.Prediction(aggregateModel.Name, input).Property("avg"); var index = IndexBuilder.ValueIndex(ValueIndexItem.Expression(sumPrediction), ValueIndexItem.Expression(avgPrediction)); Db.CreateIndex("SumAvgIndex", index); aggregateModel.AllowCalls = false; using (var q = QueryBuilder.Select(SelectResult.Expression(sumPrediction).As("s"), SelectResult.Expression(avgPrediction).As("a")) .From(DataSource.Database(Db)) .Where(sumPrediction.EqualTo(Expression.Int(15)).And(avgPrediction.EqualTo(Expression.Int(3))))) { var explain = q.Explain(); explain.IndexOf("USING INDEX SumAvgIndex").Should().NotBe(-1, "because the sum index should be used"); var numRows = VerifyQuery(q, (n, r) => { r.GetLong(0).Should().Be(15); r.GetLong(1).Should().Be(3); }); numRows.Should().Be(1); aggregateModel.NumberOfCalls.Should().Be(4); } }
public void TestCreateSameNameIndexes() { var fName = Expression.Property("firstName"); var lName = Expression.Property("lastName"); var fNameItem = ValueIndexItem.Expression(fName); var fNameIndex = IndexBuilder.ValueIndex(fNameItem); Db.CreateIndex("myindex", fNameIndex); var lNameItem = ValueIndexItem.Expression(lName); var lNameIndex = IndexBuilder.ValueIndex(lNameItem); Db.CreateIndex("myindex", lNameIndex); Db.GetIndexes().ShouldBeEquivalentTo(new[] { "myindex" }, "because lNameIndex should overwrite fNameIndex"); var detailItem = FullTextIndexItem.Property("detail"); var detailIndex = IndexBuilder.FullTextIndex(detailItem); Db.CreateIndex("myindex", detailIndex); Db.GetIndexes().ShouldBeEquivalentTo(new[] { "myindex" }, "because detailIndex should overwrite lNameIndex"); }
public void TestDeletePredictiveIndexesSharedCache() { CreateDocument(1, 2, 3, 4, 5); CreateDocument(6, 7, 8, 9, 10); var aggregateModel = new AggregateModel(); aggregateModel.RegisterModel(); var model = nameof(AggregateModel); var input = AggregateModel.CreateInput("numbers"); var prediction = Function.Prediction(model, input); var aggIndex = IndexBuilder.PredictiveIndex(model, input, null); Db.CreateIndex("AggIndex", aggIndex); var sumIndex = IndexBuilder.PredictiveIndex(model, input, "sum"); Db.CreateIndex("SumIndex", sumIndex); var avgIndex = IndexBuilder.PredictiveIndex(model, input, "avg"); Db.CreateIndex("AvgIndex", avgIndex); using (var q = QueryBuilder.Select(SelectResult.Property("numbers")) .From(DataSource.Database(Db)) .Where(prediction.Property("sum").LessThanOrEqualTo(Expression.Int(15)).Or( prediction.Property("avg").EqualTo(Expression.Int(8))))) { var explain = q.Explain(); explain.Contains("USING INDEX SumIndex").Should().BeTrue(); explain.Contains("USING INDEX AvgIndex").Should().BeTrue(); var rows = VerifyQuery(q, (n, result) => { result.GetArray(0)?.Count.Should().BeGreaterThan(0); }); aggregateModel.Error.Should().BeNull(); rows.Should().Be(2); aggregateModel.NumberOfCalls.Should().Be(2); } Db.DeleteIndex("SumIndex"); // Note: With only one index, the SQLite optimizer does not utilize the index // when using an OR expression. So test each query individually. aggregateModel.Reset(); aggregateModel.AllowCalls = false; using (var q = QueryBuilder.Select(SelectResult.Property("numbers")) .From(DataSource.Database(Db)) .Where(prediction.Property("sum").EqualTo(Expression.Int(15)))) { var explain = q.Explain(); explain.Contains("USING INDEX SumIndex").Should().BeFalse(); var rows = VerifyQuery(q, (n, result) => { result.GetArray(0)?.Count.Should().BeGreaterThan(0); }); aggregateModel.Error.Should().BeNull(); rows.Should().Be(1); aggregateModel.NumberOfCalls.Should().Be(0); } aggregateModel.Reset(); aggregateModel.AllowCalls = false; using (var q = QueryBuilder.Select(SelectResult.Property("numbers")) .From(DataSource.Database(Db)) .Where(prediction.Property("avg").EqualTo(Expression.Int(8)))) { var explain = q.Explain(); explain.Contains("USING INDEX AvgIndex").Should().BeTrue(); var rows = VerifyQuery(q, (n, result) => { result.GetArray(0)?.Count.Should().BeGreaterThan(0); }); aggregateModel.Error.Should().BeNull(); rows.Should().Be(1); aggregateModel.NumberOfCalls.Should().Be(0); } Db.DeleteIndex("AvgIndex"); for (int i = 0; i < 2; i++) { aggregateModel.Reset(); aggregateModel.AllowCalls = i == 1; using (var q = QueryBuilder.Select(SelectResult.Property("numbers")) .From(DataSource.Database(Db)) .Where(prediction.Property("avg").EqualTo(Expression.Int(8)))) { var explain = q.Explain(); explain.Contains("USING INDEX SumIndex").Should().BeFalse(); explain.Contains("USING INDEX AvgIndex").Should().BeFalse(); var rows = VerifyQuery(q, (n, result) => { result.GetArray(0)?.Count.Should().BeGreaterThan(0); }); aggregateModel.Error.Should().BeNull(); rows.Should().Be(1); if (i == 0) { aggregateModel.NumberOfCalls.Should().Be(0); } else { aggregateModel.NumberOfCalls.Should().BeGreaterThan(0); } } Db.DeleteIndex("AggIndex"); } }