App下載

關(guān)于RavenDB中的遞歸索引的使用方法分享!

發(fā)呆業(yè)務(wù)愛好者 2021-09-24 16:17:52 瀏覽數(shù) (2441)
反饋

基于權(quán)限的圖查詢

在這篇文章中,我想展示另一種處理相同問題的方法,但不使用圖形查詢,只使用我們?cè)?RavenDB 4.1 中的功能。

這個(gè)想法是,給定一個(gè)用戶,我希望能夠?qū)υ撚脩粲袡?quán)訪問的所有問題發(fā)出查詢,要么直接(如圖中的 Sunny),要么通過一個(gè)組(如 Max,通過 project-x 組) ) 或通過遞歸組,例如 (Nati,通過 project-x –> team-nati 組)。

從這篇文章的名稱可以想象,這需要遞歸。您可以閱讀有關(guān)此的文檔,但我想增加一些趣味并同時(shí)使用多個(gè)功能。

我們來看下面的索引(Issues/Permissions):

// Issues/Permissions index definition

map("Issues", issue =>{
   var groups = issue.Groups.reduce(recurse_groups, {});
   return  { Groups: Object.keys(groups), Users: issue.Users };
});

function recurse_groups(accumulator, grpId) {
    if(grpId == null || accumulator.hasOwnProperty(grpId))
        return accumulator;
    accumulator[grpId] = null; 
    var grp = load(grpId, "Groups");
    if(grp == null || grp.Parents == null)
        return accumulator;
    return grp.Parents.reduce(recurse_groups, accumulator);
}

這是一個(gè) JS 索引,它在 Issues 集合上有一個(gè) map() 函數(shù)。對(duì)于每個(gè)問題,我們?yōu)閱栴}的用戶和允許訪問它的組(遞歸地)編制索引。

對(duì)于圖中的問題,此索引的輸出如下:

圖片

現(xiàn)在讓我們看看如何查詢這個(gè)。

用兩個(gè)子句查詢

這個(gè)查詢有兩個(gè)子句;要么直接分配給我們,要么通過一個(gè)小組分配給我們。這里的關(guān)鍵是在recurse_groups () 和里面,索引中的load()調(diào)用。它向上掃描定義的組及其父級(jí),直到我們?cè)谒饕杏幸粋€(gè)易于搜索的簡(jiǎn)單結(jié)構(gòu)。

RavenDB 將確保每當(dāng)索引中的load()引用的文檔被更新時(shí),所有引用它的文檔都將被重新索引。在我們這里的情況下,每當(dāng)更新組時(shí),我們都會(huì)重新索引所有相關(guān)問題以匹配新的權(quán)限結(jié)構(gòu)。

RavenDB 的核心原則之一是您可以將更多工作推向索引并保持查詢快速和簡(jiǎn)單。這是一個(gè)很好的例子,說明我們?nèi)绾我砸环N非常優(yōu)雅的方式將工作推送到后臺(tái)索引的方式排列數(shù)據(jù)。


1 人點(diǎn)贊