logo

NJP

How to Get Only the Newest Knowledge Articles in ServiceNow (Explained Like You're 5!)

New article articles in ServiceNow Community Β· Jul 07, 2025 Β· article

Intro:

I was tasked with creating a script to fetch Knowledge Articles linked to Application CIs, but there was a catch - I only wanted the latest version of each article. When KB articles get updated, ServiceNow creates new versions but keeps the old ones, so I was getting duplicates.

The Problem:

  • KB0001234 Version 1.0
  • KB0001234 Version 2.0
  • KB0001234 Version 3.0 ← Only want this one!

My Big Challenge: Too Many Comic Books! πŸ“š

Imagine you have a huge pile of comic books, but some comics have multiple versions:

  • Spider-Man #100 Version 1 (old and torn) πŸ“–
  • Spider-Man #100 Version 2 (better) πŸ“—
  • Spider-Man #100 Version 3 (brand new and shiny!) βœ¨πŸ“˜
  • Batman #200 Version 1 (old) πŸ“–
  • Batman #200 Version 2 (new and shiny!) βœ¨πŸ“—

My job: Pick only the newest, shiniest version of each comic for my friend!

But in ServiceNow, these "comic books" are called Knowledge Articles, and they work the same way - when someone updates an article, ServiceNow keeps the old versions too!

My First Idea: "I Saw This Trick!" πŸ€”

I was looking at the ServiceNow screen where all the Knowledge Articles are listed, and I saw something cool - they were grouped together by number! It looked like this:

πŸ“š Spider-Man #100
   - Version 1
   - Version 2  
   - Version 3

πŸ“š Batman #200
   - Version 1
   - Version 2

I thought: "Perfect! I saw groupBy('number') in the code that makes this happen. I'll use the same trick!"

// My first try (WRONG!)
grKB.groupBy('number'); // I saw this working on the screen!

Why I thought this would work:

  • It was literally working on the ServiceNow screen
  • The articles looked nicely grouped by number
  • I figured if it works on the screen, it should work in my code
  • It seemed super obvious!

Why My First Idea Didn't Work 😒

Here's the tricky part I learned:

Looking at comics on a shelf vs. Picking comics to take home are DIFFERENT things!

  • On the shelf (List View): groupBy() organizes comics so you can see them nicely
  • Picking comics (My Script): I need to actually grab individual comics to take home

The Problem: When I tried to "pick up" comics using my script, groupBy() was like asking the librarian "How many Spider-Man comics do you have?" instead of "Give me the newest Spider-Man comic!"

I needed actual comic books to take home, not just a count of how many there were!

My Working Solution: Line Them Up + Pick Smart! 🎯

I figured out a better way - like organizing a comic book store:

Step 1: Line Up All Comics (Newest First!) πŸ“

grKB.orderByDesc('number');     // Group same comics together
grKB.orderByDesc('version');    // Put newest versions first in line

Now my line looks like:

Spider-Man #100 Version 3 ← NEWEST! (first in line)
Spider-Man #100 Version 2 ← older
Spider-Man #100 Version 1 ← oldest
Batman #200 Version 2 ← NEWEST! (first in line)  
Batman #200 Version 1 ← older

Step 2: Use My Memory Box! πŸ§ πŸ“¦

var processedNumbers = {}; // My magic memory box (starts empty)

This is like having a notebook where I write down which comics I already picked!

Step 3: Walk Down the Line and Pick Smart! πŸšΆβ€β™‚οΈ

while (grKB.next()) { // Walk to each comic in line
    var articleNumber = grKB.number.toString(); // What comic is this?

    // Check my memory box: "Have I seen this comic number before?"
    if (!processedNumbers[articleNumber]) {
        // "Nope! Never seen this comic number!"
        processedNumbers[articleNumber] = true; // Write it in my memory box ✍️

        // Take this comic! (It's the newest because it's first in line!)
        articles.push({
            sys_id: grKB.sys_id.toString(),
            number: articleNumber,
            // ... other comic details
        });
    }
    // If I already have this comic number, skip it!
}

Let's Watch It Work! πŸ‘€

Memory box starts empty: {}

Comic 1: Spider-Man #100 Version 3

  • Me: "Have I seen #100 before?"
  • Memory box: {} (empty - nope!)
  • Me: "Take it!" πŸ“˜βœ…
  • Memory box now: {100: true}

Comic 2: Spider-Man #100 Version 2

  • Me: "Have I seen #100 before?"
  • Memory box: {100: true} (yes, I have it!)
  • Me: "Skip it!" ❌

Comic 3: Spider-Man #100 Version 1

  • Me: "Have I seen #100 before?"
  • Memory box: {100: true} (yes, still have it!)
  • Me: "Skip it!" ❌

Comic 4: Batman #200 Version 2

  • Me: "Have I seen #200 before?"
  • Memory box: {100: true} (nope, no #200!)
  • Me: "Take it!" πŸ“—βœ…
  • Memory box now: {100: true, 200: true}

Comic 5: Batman #200 Version 1

  • Me: "Have I seen #200 before?"
  • Memory box: {100: true, 200: true} (yes, I have it!)
  • Me: "Skip it!" ❌

My Complete Working Code! πŸŽ‰

var KBArticleHelper = Class.create();
KBArticleHelper.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    getKBArticles: function() {
        var parentId = this.getParameter('sysparm_parent_id');
        var articles = [];

        // Get all the knowledge articles
        var grKB = new GlideRecord('kb_knowledge');
        grKB.addQuery('cmdb_ci', parentId);
        grKB.addQuery('active', true);
        grKB.addQuery('workflow_state', 'published');

        // Step 1: Line them up (newest first!)
        grKB.orderByDesc('number');
        grKB.orderByDesc('version'); 
        grKB.query();

        // Step 2: Get my memory box ready
        var processedNumbers = {}; 

        // Step 3: Walk down the line and pick smart!
        while (grKB.next()) {
            var articleNumber = grKB.number.toString();

            // Check memory box: "Have I seen this number before?"
            if (!processedNumbers[articleNumber]) {
                processedNumbers[articleNumber] = true; // Remember it!

                // Take this article (it's the newest!)
                articles.push({
                    sys_id: grKB.sys_id.toString(),
                    number: articleNumber,
                    short_description: grKB.short_description.toString(),
                    category: grKB.kb_category.getDisplayValue(),
                    validTo: grKB.valid_to.getDisplayValue(),
                    updatedOn: grKB.sys_updated_on.getDisplayValue(),
                    owner_group: grKB.ownership_group.getDisplayValue(),
                });
            }
            // If I already have this number, just keep walking!
        }

        return JSON.stringify(articles);
    },
    type: 'KBArticleHelper'
});

What I Learned (So You Don't Make My Mistakes!) πŸŽ“

1. Screen Magic β‰  Code Magic

Just because something works on the ServiceNow screen doesn't mean it works the same way in your code!

  • Screen groupBy = "Show me things organized nicely"
  • Code groupBy = "Count things for me"
  • What I needed = "Give me actual things to work with"

2. Simple Ideas Work Best! πŸ’‘

My fancy groupBy idea didn't work, but simple "line up + memory box" worked perfectly!

3. Test Your Ideas! πŸ§ͺ

Always try your code in a safe place first. My first idea seemed super smart but didn't work!

4. It's Okay to Be Wrong First! 😊

Every expert was once a beginner who tried things that didn't work. That's how we learn!

When to Use My Trick! 🎯

Use this "Line Up + Memory Box" trick when you need:

  • Only the newest version of things
  • The first one of each type
  • To avoid duplicates but keep all the details
  • Something simple that's easy to understand

Final Thoughts! 🌟

Don't be scared to try different ideas! My first groupBy idea didn't work, but it helped me understand the problem better and find the right solution.

Remember:

  • Test your ideas in a safe place
  • Simple solutions are often the best
  • It's okay if your first idea doesn't work
  • Every expert started as a beginner just like you!

The most important thing is to keep trying until something works! πŸš€


A Note from Me πŸ’­

I know there are probably better explanations about this topic out there, but my intention is not to duplicate anyone's efforts. This is simply how I learned and thought it might be useful for someone out there just like me. I'm not an expert JavaScript developer or pro coder - I'm still learning every day!

This article is my way of sharing my learning journey, hoping it might help another beginner who faces the same challenge. We all learn differently, and sometimes a simple, personal explanation can click better than complex technical documentation.

If you believe this solution has adequately addressed a similar query you might have had, could you please mark it as 'Helpful'? This will help other community members who might have the same question find the answer more easily.

Thank you for your consideration, and happy coding! 🎈✨

Remember: Every expert was once a beginner. Keep learning, keep trying, and don't be afraid to share your journey with others!

Selva Arun

View original source

https://www.servicenow.com/community/developer-articles/how-to-get-only-the-newest-knowledge-articles-in-servicenow/ta-p/3312938