簡體   English   中英

從IBM Domino檢索大數據

[英]Large data retrieval from IBM Domino

我正在嘗試從IBM Domino v9.0收集帳戶數據和組數據。

我編寫的用於收集數據的代碼使用了lotus.domino.View API。 該代碼適用於少量數據集,我為40個用戶運行了該代碼,這很好。 當我運行代碼以提取10k用戶的數據時,大約需要3-4個小時來提取數據,這是不可接受的。

您能否建議我一些其他的API,以便我們以更快的速度檢索數據?

我當前使用的代碼如下:

private static void testUserDataRetrieval(String host, String userName, String password) throws Exception{
    Session s = NotesFactory.createSession(host, userName, password);
    Database db = s.getDatabase(s.getServerName(), "names");
    File outFile = new File("C:\\Users\\vishva\\Desktop\\dominoExtract.txt");
    FileWriter writer = new FileWriter(outFile);
    View view = db.getView("($Users)");
    ViewEntryCollection entryCollection = view.getAllEntries();
    writer.write("\n--------------------------------- Printing data for view:"+view.getName()+"("+view.getEntryCount()+")--------------------------------------------");
    Vector<Object> columnNames = view.getColumnNames();
    for(int i = 0; i< entryCollection.getCount(); i++){
        ViewEntry entry = entryCollection.getNextEntry();
        if(entry == null) continue;
        Vector<Object> colValues = entry.getColumnValues();
        for(int j = 0; j < columnNames.size(); j++)
            writer.write("\n"+columnNames.get(j)+":"+colValues.get(j));
        writer.write("\n*****************************************");
    }
    writer.flush();
    writer.close();
}

請讓我知道我應該使用其他哪個API來提高數據檢索的速度?

首先:在for循環的每次運行中讀取集合的計數。 這使其非常緩慢。 完全不需要for循環。 第二:您永遠不會回收對象。 在使用多米諾骨牌對象時,這是必須的,否則您的代碼將以比您想象的更快的速度消耗內存:

private static void testUserDataRetrieval(String host, String userName, String password) throws Exception{
  Session s = NotesFactory.createSession(host, userName, password);
  Database db = s.getDatabase(s.getServerName(), "names");
  File outFile = new File("C:\\Users\\vishva\\Desktop\\dominoExtract.txt");
  FileWriter writer = new FileWriter(outFile);
  View view = db.getView("($Users)");
  ViewEntryCollection entryCollection = view.getAllEntries();
  writer.write("\n--------------------------------- Printing data for view:"+view.getName()+"("+view.getEntryCount()+")--------------------------------------------");
  Vector<Object> columnNames = view.getColumnNames();
  ViewEntry entry = entryCollection.getFirstEntry();
  ViewEntry entryNext;
  while(entry != null) {
    Vector<Object> colValues = entry.getColumnValues();
    for(int j = 0; j < columnNames.size(); j++)
        writer.write("\n"+columnNames.get(j)+":"+colValues.get(j));
    writer.write("\n*****************************************");
    entryNext = entryCollection.getNextEntry();
    entry.recycle();
    entry = entryNext ;
  }

writer.flush();
writer.close();

}

默認情況下,您的View對象的isAutoUpdate屬性設置為true。 這意味着它將與后端發生的任何更改同步 ,而不僅僅是給您一次性快照。 添加:

view.setAutoUpdate(false);

另外,您可能應該使用ViewNavigator類進行調查。 請參閱此處以獲得詳細描述從Domino 8.5.2開始該類中的性能改進的文章。 它是由班級的主要開發人員編寫的。 另請參閱此博客文章,以獲得很多有趣的細節。

感謝大家的投入。 為了檢索用戶,我稍后嘗試了LDAP API,它的工作原理很吸引人。 我能夠在23秒內檢索到1 萬個帳戶 ,這是可以接受的。 我使用的代碼如下

    private void extractDominoDataViaLdap(){
    String [] args = new String[]{"192.168.21.156","Administrator","password","","C:\\Users\\vishva\\Desktop"};
    String server = args[0];
    String userName = args[1];
    String password = args[2];
    String baseDN = args[3];
    String fileLocation = args[4];
    // Set up environment for creating initial context
    Hashtable<String, Object> env = new Hashtable<String, Object>(11);
    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://"+server+":389");

    long time = System.currentTimeMillis();
    // Authenticate as S. User and password "mysecret"
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, userName);
    env.put(Context.SECURITY_CREDENTIALS, password);
    FileWriter writer = null;
    BufferedWriter out = null;
    try {
        DirContext ctx = new InitialDirContext(env);
        //fetching user data
        // Create the search controls
        SearchControls searchCtls = new SearchControls();
        // Specify the attributes to return
        String returnedAtts[] = {"FullName","dn","displayname","givenName","sn","location","mail","mailfile","mailserver"};
        searchCtls.setReturningAttributes(returnedAtts);
        // Specify the search scope
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchCtls.setCountLimit(0);
        // specify the LDAP search filter
        String searchFilter = "objectClass=inetOrgPerson";

        // Specify the Base for the search
        String searchBase = baseDN;

        // Search for objects using the filter
        NamingEnumeration<SearchResult> answer = ctx.search(searchBase,searchFilter, searchCtls);

        writer = new FileWriter(fileLocation+"\\users.csv");
        out = new BufferedWriter(writer);
        for(String attr : returnedAtts)
            out.write(attr+",");
        out.write("\n");
        int count = 0;
        // Loop through the search results
        while (answer.hasMoreElements()) {
            ++count;
            SearchResult sr = (SearchResult) answer.next();
            Attributes attrs = sr.getAttributes();
            StringBuilder sb = new StringBuilder();
            for(String attr : returnedAtts)
                sb.append("\""+((attrs.get(attr) != null)?attrs.get(attr).get():"")+"\"").append(",");
            out.write(sb.toString()+"\n");
            out.flush();
        }
        System.out.println("# of users returned: "+count);
        out.close();
        writer.close();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM