+ Start a Discussion
sushieatersushieater 

finding out articletype from knowledgeArticleVersion

I am performing sosl queries to return knowledge articles similar to this.

 

find {test} IN ALL FIELDS RETURNING KnowledgeArticleVersion ( id,title, urlName where publishStatus='online' and language='en_US')

 

How can I find out what type of article each result is? 

 

I don't want to have the sosl return a seperate list for each article type as I would like to keep the articles ranked based on the search term as stronly as possible. I'm only interested in a max of 5 returned records and I have 5 article types.

 

I can't find a good solution to this. Two possible solutions

 

1) for each id returned, query each article type to see if a record is returned

SELECT count() FROM faq__kav where id = 'ka4S0000000CaTSIA0'

...

SELECT count() FROM documentation__kav where id = 'ka4S0000000CaTSIA0'

 

So if I'm returning 5 records in my sosl, I could have up to 25 soql queries if I have 5 article types.

 

2) query knowledgeArticleVersion and the individual article Types in sosl. Take the list of knowledgeArticleVersions and then iterate through the other lists to see which articleType list it belongs to.

 

find {test} IN ALL FIELDS RETURNING KnowledgeArticleVersion ( id,title, urlName where publishStatus='online' and language='en_US'), faq__kav (id), documentation__kav(id)...

 

Is there a better way that I'm missing?

 

Thanks,.

 

Best Answer chosen by Admin (Salesforce Developers) 
francoisLfrancoisL

Hi,

 

There is another solution by using record id. If you took the first 3 letter of article id, you can find what is the article type.

 

See an exmaple here:

// Create DescribeMap
    private void createDescribeMap() {
        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        Set<String> keySet = gd.keySet();
        for (String key : keySet) {
            Schema.SObjectType objectType = gd.get(key);
            if (key.endsWith('ka') || key.endsWith('kb')) {
                this.describeMap.put(objectType.getDescribe().getKeyPrefix(), objectType.getDescribe().getLabel());
            }
        }
    }

//Util method to get Article Type from article Id.
    public String getArticleType(String articleId) {
        String articlePrefix = articleId.substring(0,3);
        Set<String> keySet = describeMap.keySet();
        String articleType = null;
        for(String key: keySet) {
            if(articlePrefix.equalsIgnoreCase(key)) {
                articleType = describeMap.get(key);
                return articleType;
            }
        }
        return articleType;
    }

 

 

All Answers

francoisLfrancoisL

Hi,

 

There is another solution by using record id. If you took the first 3 letter of article id, you can find what is the article type.

 

See an exmaple here:

// Create DescribeMap
    private void createDescribeMap() {
        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        Set<String> keySet = gd.keySet();
        for (String key : keySet) {
            Schema.SObjectType objectType = gd.get(key);
            if (key.endsWith('ka') || key.endsWith('kb')) {
                this.describeMap.put(objectType.getDescribe().getKeyPrefix(), objectType.getDescribe().getLabel());
            }
        }
    }

//Util method to get Article Type from article Id.
    public String getArticleType(String articleId) {
        String articlePrefix = articleId.substring(0,3);
        Set<String> keySet = describeMap.keySet();
        String articleType = null;
        for(String key: keySet) {
            if(articlePrefix.equalsIgnoreCase(key)) {
                articleType = describeMap.get(key);
                return articleType;
            }
        }
        return articleType;
    }

 

 

This was selected as the best answer
sushieatersushieater

Thanks very much. 

LukashPLukashP

+ for this solution :)

StephenDavidsonStephenDavidson

 public AgentContributionArticleController(ApexPages.KnowledgeArticleVersionStandardController ctl) {
        SObject article = ctl.getRecord();   //this is the SObject for the new article.
                                             //It can optionally be cast to the proper article type, e.g. FAQ__kav article = (FAQ__kav) ctl.getRecord();
    
        String sourceId = ctl.getSourceId(); //this returns the id of the case that was closed.
        Case c = [select subject, description,casenumber, defect_1__c from Case where id=:sourceId];
        CaseComment cc = [select LastModifiedDate, LastModifiedBy.Id, LastModifiedBy.Name, IsPublished, CreatedDate, CreatedBy.Id, CreatedBy.Name, CommentBody From CaseComment where ParentId = :sourceId order by LastModifiedDate desc limit 1];
     

  //check article type with if statement


        String strArticle = article.Id;
        String strArticlePrefix = strArticle.substring(0,3);
        Set<String> keySet = describeMap.keySet();
        String articleType = null;
        for(String key: keySet) {
            if(articlePrefix.equalsIgnoreCase(key)) {
                articleType = describeMap.get(key);
                return articleType;
            }
        }
I get this error

 

Error

Error: Compile Error: Method does not exist or incorrect signature: describeMap.keySet() at line 13 column 30

 

 

 

SO then I add the private method in you sample

NO DIfference.

Maybe I am doing something silly here but I am not a coding master

LukashPLukashP

I don't see you declaring the describeMap anywhere ...

It should be probably like 

Map<String,String> describeMap 

somewhere on the class level.

StephenDavidsonStephenDavidson

Per your suggestion, here is my code

 

       Map<String,String> describeMap;
        String strArticle = article.Id;
        String strArticlePrefix = strArticle.substring(0,3);
        Set<String> keySet = describeMap.keySet();
        String articleType = null;
        for(String key: keySet) {
            if(strArticlePrefix.equalsIgnoreCase(key)) {
                articleType = describeMap.get(key);
                article.put('title',articleType);
            }
        }

 

When I try to create an article at case close, I ge:

 

Attempt to de-reference a null object

 

If you have an idea, great!

 

 

LukashPLukashP

Check what is the line that you get the error and fix it :).

That seems like a normal error message.

StephenDavidsonStephenDavidson

Yeah, normally, I would do that.  But I am still a newbie in salesforce and coming up to speed. 

 

And I don't quite understand the sample.  DO I use both methods?  It doesn't look like the sample provided by Francois has any reference from the one method to the other.

I know if I were a master coder, I  would be able to take the two methods and presto/chango make the mods that I need to make to make it work in my code.  But...the sample provided is not something I can plug and play. 

 

THanks for you help anyway....

 

 

 

S91084S91084

With winter 13 release,  you will be able to access the ArticleType field in the KnowlegeArticleVersion in apec class with version 26.0