1.聚合缓存
RavenDb默认是缓存所有的请求url的,最大的缓存请求数默认是2048
documentStore.Conventions.ShouldCacheRequest = url => true;
documentStore.MaxNumberOfCachedRequests = 2048;
如果开启这个选项,RavenDb直接从缓存当中读取数据,而不是从服务端。
//关闭跟踪
documentStore.Conventions.ShouldAggressiveCacheTrackChanges = false;
using (session.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(5)))
{
var user = session.Load<User>("users/1");
}
using (session.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(5)))
{
var user = session.Load<User>("users/1");
}
//启动强制检查更新,在SaveChanges之后
documentStore.Conventions.ShouldSaveChangesForceAggresiveCacheCheck = true;
2、客户端Listener
Document Conflict listeners (IDocumentConflictListener),
Document Conversion listeners (IDocumentConversionListener)
Document Delete listeners (IDocumentDeleteListener)
Document Query listeners (IDocumentQueryListener)
Document Store listeners (IDocumentStoreListener)
例子1:
public class TakeNewestConflictResolutionListener : IDocumentConflictListener
{
public bool TryResolveConflict(string key, JsonDocument[] conflictedDocs, out JsonDocument resolvedDocument)
{
var maxDate = conflictedDocs.Max(x => x.LastModified);
resolvedDocument = conflictedDocs.FirstOrDefault(x => x.LastModified == maxDate);
return resolvedDocument != null;
}
}
例子2:
public class Custom
{
public string Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
public class MetadataToPropertyConversionListener : IDocumentConversionListener
{
public void EntityToDocument(string key, object entity, RavenJObject document, RavenJObject metadata)
{
if (entity is Custom == false)
return;
document.Remove("Value");
}
public void DocumentToEntity(string key, object entity, RavenJObject document, RavenJObject metadata)
{
if (entity is Custom == false)
return;
((Custom)entity).Value = metadata.Value<string>("Raven-Document-Revision");
}
}
例子3:
public class FailDelete : IDocumentDeleteListener
{
public void BeforeDelete(string key, object entityInstance, RavenJObject metadata)
{
throw new NotSupportedException();
}
}
例子4:
public class NonStaleQueryListener : IDocumentQueryListener
{
public void BeforeQueryExecuted(IDocumentQueryCustomization customization)
{
customization.WaitForNonStaleResults();
}
}
例子5:
public class FilterForbiddenKeysDocumentListener : IDocumentStoreListener
{
private readonly IList<string> forbiddenKeys = new List<string> { "system" };
public bool BeforeStore(string key, object entityInstance, RavenJObject metadata, RavenJObject original)
{
return this.forbiddenKeys.Any(x => x.Equals(key, StringComparison.InvariantCultureIgnoreCase)) == false;
}
public void AfterStore(string key, object entityInstance, RavenJObject metadata)
{
}
}
3、批量插入
//批量插入代码示例
using (var bulkInsert = store.BulkInsert())
{
for (int i = 0; i < 1000 * 1000; i++)
{
bulkInsert.Store(new User
{
Name = "Users #" + i
});
}
}
//批量插入接口原型
public interface IDocumentStore
{
BulkInsertOperation BulkInsert(string database = null, BulkInsertOptions options = null);
}
//批量插入选项原型
public class BulkInsertOptions
{
public bool CheckForUpdates { get; set; }
public bool CheckReferencesInIndexes { get; set; }
public int BatchSize { get; set; }
}
//批量插入操作原型
public class BulkInsertOperation
{
public delegate void BeforeEntityInsert(string id, RavenJObject data, RavenJObject metadata);
public event BeforeEntityInsert OnBeforeEntityInsert = delegate { };
public event Action<string> Report { ... }
public void Store(object entity) { ... }
public void Store(object entity, string id) { ... }
}
4、流式查询
默认的分页查询的,但是有时候,我们需要一次性查询,RavenDb提供了一种流式查询的方式
//正常查询
var query = session.Query<User>("Users/ByActive").Where(x => x.Active);
using (var enumerator = session.Advanced.Stream(query))
{
while (enumerator.MoveNext())
{
User activeUser = enumerator.Current.Document;
}
}
//lucene查询
var luceneQuery = session.Advanced.LuceneQuery<User>("Users/ByActive").Where("Active:true");
using (var enumerator = session.Advanced.Stream(luceneQuery))
{
while (enumerator.MoveNext())
{
User activeUser = enumerator.Current.Document;
}
}
//接口原型
QueryHeaderInformation queryHeaderInformation;
session.Advanced.Stream(query, out queryHeaderInformation);
public class QueryHeaderInformation
{
public string Index { get; set; }
public bool IsStable { get; set; }
public DateTime IndexTimestamp { get; set; }
public int TotalResults { get; set; }
public Etag ResultEtag { get; set; }
public Etag IndexEtag { get; set; }
}
//分页
using (var enumerator = session.Advanced.Stream<User>(fromEtag: Etag.Empty,
start: 0, pageSize: int.MaxValue))
{
while (enumerator.MoveNext())
{
User activeUser = enumerator.Current.Document;
}
}
//
using (var enumerator = session.Advanced.Stream<User>(startsWith: "users/",
matches: "*Ra?en",
start: 0, pageSize: int.MaxValue))
{
while (enumerator.MoveNext())
{
User activeUser = enumerator.Current.Document;
}
}
//异步版本
using (var asyncSession = store.OpenAsyncSession())
{
var query = asyncSession.Query<User>("Users/ByActive").Where(x => x.Active);
using (var enumerator = await asyncSession.Advanced.StreamAsync(query))
{
while (await enumerator.MoveNextAsync())
{
User activeUser = enumerator.Current.Document;
}
}
using (var enumerator = await asyncSession.Advanced.StreamAsync<User>(Etag.Empty))
{
while (await enumerator.MoveNextAsync())
{
User activeUser = enumerator.Current.Document;
}
}
}