How to display knowledge base hierarchy

Recently I was asked by Knowledgebase Manager why she was not able to remove an unnecessary category in ServiceNow. The answer was simple: there is an ACL which checks if a category has a child, either article or other category. We found a retired article which was still linked to this category. Because of that, it was impossible to delete this category.

It was a quick fix. But I can imagine a more complex knowledge base with more levels of orphaned categories and articles. That’s why I wrote the below script. Function get KnowledgeBase() prints the whole knowledge base in a hierarchical way. Thanks to that, you can quickly check its construction. Or you can display only one specific knowledge base by providing the name as a parameter.

_creteArticleObject = function(articleRecord) {
	return {
		number: articleRecord.getValue('number'),
		article: articleRecord.getValue('short_description')
	};
};

_getQueryForArticles = function (parentType, parentSysId) {
	var sql = parentType + '=' + parentSysId;
	sql += parentType === 'kb_knowledge_base' ? '^kb_categoryISEMPTY': '';
	return sql;
};

getArticles = function(parentType, parentSysID){
	var articles = [],
	articleObject,
	sql,
	articleRecord;
	
	sql = _getQueryForArticles(parentType, parentSysID);
	
	articleRecord = new GlideRecord('kb_knowledge');
	articleRecord.addEncodedQuery(sql);
	articleRecord.query();
	
	while (articleRecord.next()) {
		articles.push(_creteArticleObject(articleRecord));
	}
	return articles;
};

_creteCategoryObject = function(categoryRecord) {
	var catgoryRecordSysId = categoryRecord.getUniqueValue();
	return {
		sys_id: catgoryRecordSysId,
		category: categoryRecord.getValue('label'),
		categories: getCategories(catgoryRecordSysId),
		articles: getArticles('kb_category', catgoryRecordSysId)
	};
};

getCategories = function(parentId) {
	var categories = [],
	categoryRecord;
	
	categoryRecord = new GlideRecord('kb_category');
	categoryRecord.addQuery('parent_id', parentId);
	categoryRecord.query();
	
	while (categoryRecord.next()) {
		categories.push(_creteCategoryObject(categoryRecord));
	}
	return categories;
};

_createKnowledgeBaseHierarchyObject = function(knowledgeBaseRecord) {
	var knowledgeBaseSysId = knowledgeBaseRecord.getUniqueValue();
	return {
		sys_id: knowledgeBaseSysId,
		knowledgebase: knowledgeBaseRecord.getValue('title'),
		categories: getCategories(knowledgeBaseSysId),
		articles: getArticles('kb_knowledge_base', knowledgeBaseSysId)
	};
};

_getTitleQueryForKnowledgBases = function(knowledgeBaseTitle){
	return knowledgeBaseTitle ? 'title='+knowledgeBaseTitle : 'titleANYTHING';
};

getKnowledgeBases = function(title){
	var knowledgeBases = [],
	knowledgeBaseRecord,
	knowledgeBaseSysId,
	sql;
	
	sql = _getTitleQueryForKnowledgBases(title);
	
	knowledgeBaseRecord = new GlideRecord('kb_knowledge_base');
	knowledgeBaseRecord.addEncodedQuery(sql);
	knowledgeBaseRecord.query();
	
	while (knowledgeBaseRecord.next()) {
		knowledgeBases.push(_createKnowledgeBaseHierarchyObject(knowledgeBaseRecord));
	}
	return knowledgeBases;
};

gs.info(JSON.stringify(getKnowledgeBases('IT'), null, 2));

Leave a Reply

Your email address will not be published. Required fields are marked *