- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-17-2023 01:32 AM
I'm trying to get some statistics on our Knowledge Articles. I need to know word count, average length of the body, average number of characters, shortest article, longest article etc. Can anybody help?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-17-2023 01:53 AM - edited 01-17-2023 01:54 AM
At the moment there is nothing OOTB that does this. When you edit a KB you can actually see the word count (and you can see characters count by clicking on it) but it is not available to report on etc.
There is a Service Portal word count function available for free on Share though. See:
You should be able to re-purpose the code for what you need.
There is an Idea raised in the Idea portal for this so worth an upvote see:
If helpful please mark as Helpful/Correct
Regards
Paul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-17-2023 08:34 AM
Adding such functionality in ServiceNow is not a big thing:
If you want to create statistics, you must first collect the data. The best way to do this is to extend the knowledge table with the appropriate fields.
Then you add these fields to your form so that you can see it.
Now it gets a bit complicated because unfortunately the Knowledge Body field is an HTML field. So you can't just count the content, you have to omit the whole format overhead.
The easiest way to solve the task is to build a flow in the Flow Designer.
- You create a new flow that is triggered when a knowledge article is created or updated.
- You pass the content to a script that does the evaluations for you (I'll describe this below).
- And with the result of the script you make an update on your three fields.
The script can only be expressed as JavaScript. You need a programmer for that. But it is not so complicated. You create an Action in the Flow Designer, define the Input and Output variables and then you insert the script.
You can copy it from here.
(function execute(inputs, outputs) {
'use strict'
liveElements = []
const each = Array.prototype.forEach
counts = count(inputs.text)
outputs.paragraphs= counts.paragraphs
outputs.words= counts.words
outputs.characters= counts.characters
function decode (string) {
const output = []
counter = 0
const length = string.length
while (counter < length) {
const value = string.charCodeAt(counter++)
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
// It's a high surrogate, and there is a next character.
const extra = string.charCodeAt(counter++)
if ((extra & 0xFC00) == 0xDC00) { // Low surrogate.
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000)
} else {
// It's an unmatched surrogate; only append this code unit, in case the
// next code unit is the high surrogate of a surrogate pair.
output.push(value)
counter--
}
} else {
output.push(value)
}
}
return output
}
function count (target, options) {
original = '' + (typeof target === 'string' ? target : ('value' in target ? target.value : target.textContent))
options = options || {}
original = original.replace(/<\/?[a-z][^>]*>/gi, '')
if (options.ignore) {
each.call(options.ignore, function (i) {
original = original.replace(i, '')
})
}
const trimmed = original.trim()
return {
paragraphs: trimmed ? (trimmed.match(options.hardReturns ? /\n{2,}/g : /\n+/g) || []).length + 1 : 0,
words: trimmed ? (trimmed.replace(/['";:,.?¿\-!¡]+/g, '').match(/\S+/g) || []).length : 0,
characters: trimmed ? decode(trimmed.replace(/\s/g, '')).length : 0,
}
}
})(inputs, outputs);
Now you only have to publish and activate the action and the flow, and then all numbers will be automatically written into the corresponding fields as soon as you change something in an article.
And because you now have it in the table, you can do all the reports on it that you want to have.
Quite simple, isn't it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-17-2023 01:53 AM - edited 01-17-2023 01:54 AM
At the moment there is nothing OOTB that does this. When you edit a KB you can actually see the word count (and you can see characters count by clicking on it) but it is not available to report on etc.
There is a Service Portal word count function available for free on Share though. See:
You should be able to re-purpose the code for what you need.
There is an Idea raised in the Idea portal for this so worth an upvote see:
If helpful please mark as Helpful/Correct
Regards
Paul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-17-2023 08:34 AM
Adding such functionality in ServiceNow is not a big thing:
If you want to create statistics, you must first collect the data. The best way to do this is to extend the knowledge table with the appropriate fields.
Then you add these fields to your form so that you can see it.
Now it gets a bit complicated because unfortunately the Knowledge Body field is an HTML field. So you can't just count the content, you have to omit the whole format overhead.
The easiest way to solve the task is to build a flow in the Flow Designer.
- You create a new flow that is triggered when a knowledge article is created or updated.
- You pass the content to a script that does the evaluations for you (I'll describe this below).
- And with the result of the script you make an update on your three fields.
The script can only be expressed as JavaScript. You need a programmer for that. But it is not so complicated. You create an Action in the Flow Designer, define the Input and Output variables and then you insert the script.
You can copy it from here.
(function execute(inputs, outputs) {
'use strict'
liveElements = []
const each = Array.prototype.forEach
counts = count(inputs.text)
outputs.paragraphs= counts.paragraphs
outputs.words= counts.words
outputs.characters= counts.characters
function decode (string) {
const output = []
counter = 0
const length = string.length
while (counter < length) {
const value = string.charCodeAt(counter++)
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
// It's a high surrogate, and there is a next character.
const extra = string.charCodeAt(counter++)
if ((extra & 0xFC00) == 0xDC00) { // Low surrogate.
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000)
} else {
// It's an unmatched surrogate; only append this code unit, in case the
// next code unit is the high surrogate of a surrogate pair.
output.push(value)
counter--
}
} else {
output.push(value)
}
}
return output
}
function count (target, options) {
original = '' + (typeof target === 'string' ? target : ('value' in target ? target.value : target.textContent))
options = options || {}
original = original.replace(/<\/?[a-z][^>]*>/gi, '')
if (options.ignore) {
each.call(options.ignore, function (i) {
original = original.replace(i, '')
})
}
const trimmed = original.trim()
return {
paragraphs: trimmed ? (trimmed.match(options.hardReturns ? /\n{2,}/g : /\n+/g) || []).length + 1 : 0,
words: trimmed ? (trimmed.replace(/['";:,.?¿\-!¡]+/g, '').match(/\S+/g) || []).length : 0,
characters: trimmed ? decode(trimmed.replace(/\s/g, '')).length : 0,
}
}
})(inputs, outputs);
Now you only have to publish and activate the action and the flow, and then all numbers will be automatically written into the corresponding fields as soon as you change something in an article.
And because you now have it in the table, you can do all the reports on it that you want to have.
Quite simple, isn't it?