1. 程式人生 > 其它 >RavenDb學習(九)高階特性下半部分

RavenDb學習(九)高階特性下半部分

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;
        }
    }
}