Skip to main content
uelm
October 17, 2023
Solved

Get a list of all Knowledge Centers' names and sizes

  • October 17, 2023
  • 19 replies
  • 0 views

Hi all,

We're running out of disk space on our cloud environment. Appian Support has identified that the main culprits are our Knowledge Centers. They can't however identify which specific Knowledge Centers are the largest. We have over a hundred though so it may just be an accumulation of them all.

But anyway, I need to find all their individual sizes and am hoping someone knows how to do this without manually checking each Knowledge Center's properties?

An option I'm trying is: 

a!localVariables(
  local!knowledgeCenter: cons!ABC_KNOWLEDGE_CENTER_PROPERTIES,
  a!forEach(
    items: local!knowledgeCenter,
    expression: {
      creator: knowledgecenter(fv!item, "creator"),
      dateCreated: knowledgecenter(fv!item, "dateCreated"),
      description: knowledgecenter(fv!item, "description"),
      id: knowledgecenter(fv!item, "id"),
      name: knowledgecenter(fv!item, "name"),
      numberOfDocuments: knowledgecenter(fv!item, "numberOfDocuments"),
      size: knowledgecenter(fv!item, "size") / 1000000 & " MB"
    }
  )
)

Which outputs a useful list like this:

  • Dictionary
      • creator"john.wayne@domain.com"(Text)
          • dateCreated28/11/2022 12:44 GMT+02:00(Date and Time)
              • description"Folder for knowledge center"(Text)
                  • id185543(Number (Integer))
                      • name"UVW Knowledge Center"(Text)
                          • numberOfDocuments 50(Number (Integer))
                              • size "10.95459 MB"(Text)
                                    • creator"john.wayne@domain.com"(Text)
                                        • dateCreated10/07/2022 13:47 GMT+02:00(Date and Time)
                                            • description"Folder for knowledge center"(Text)
                                                • id1679445(Number (Integer))
                                                    • name"XYZ Knowledge Center"(Text)
                                                        • numberOfDocuments 38(Number (Integer))
                                                            • size "8.979983 MB"(Text)

                                                          Thing is, the Constant I'm using in the expression... I need to manually add each Knowledge Center to that Constant which also seems like a long way round:

                                                          Does anybody please have a simpler way to get a list of all Knowledge Centers and their sizes?

                                                          Many thanks,
                                                          Uel

                                                          Best answer by paulc919

                                                          I may have found a way of deriving this dynamically using the content from the healthcheck files, log reader and content tools plug ins. This works quite well in our Development Environment. 

                                                          a!localVariables(
                                                            
                                                            
                                                            /*Read Health Check log file for list of folders to get the log data*/
                                                            
                                                            local!logFile: 
                                                            fn!readcsvlog(
                                                              csvPath: "health-check/hc-document-folders.csv",
                                                              filterColumName: "Type",
                                                              filterOperator: "contains",
                                                              filterValue: "Knowledge",
                                                              headers: {"UUID","Parent UUID","Name","Type","# of Author Groups","# of Viewer Groups","# of Inherited Author Groups","# of Inherited Viewer Groups","Is KC Auto Approved for Read Only Access?","Role Map"}
                                                              
                                                              
                                                              
                                                            ),
                                                            
                                                            /*Only require the UUID from the File - Would have used Excel Tools query logs function but this does not support the health check directory yet*/
                                                            
                                                            local!kcUUID: a!forEach(
                                                              items: local!logFile.rows,
                                                              expression: split(fv!item,",")[1]
                                                            ),
                                                            
                                                            
                                                            /*Using content tools functions convert the UUID to internal ID*/
                                                            /*As a text string is returned need to break the string up into component parts - the internal ID is the 2nd entry and then */
                                                            /*we only want the value after the : value */
                                                            /*KC deletions can occur and so the getcontent fucntion will return object doesnt exist message*/
                                                            
                                                            local!kcDetails: 
                                                              a!forEach(
                                                              items: local!kcUUID,
                                                              expression: 
                                                                a!localVariables(
                                                                  local!contentObject: getcontentdetailsbyuuid(fv!item),
                                                                  local!split: split(local!contentObject, ","),
                                                                  local!kcId: if(count(local!split) > 1, tointeger(split(local!split[2],":")[2]), null),
                                                                  local!kcId
                                                                )
                                                              
                                                            ),
                                                            
                                                            
                                                            /*Remove null values - this will remove entries where the KC has been deleted post HealthCheck file creation*/
                                                            local!filteredKCDetails:  reject(a!isNullOrEmpty, local!kcDetails),
                                                            
                                                            /*Now for each entry we can get the desired values using the KC details*/
                                                            
                                                            
                                                            local!output: a!forEach(
                                                              items: local!filteredKCDetails,
                                                              expression: 
                                                              {
                                                                name: fn!knowledgecenter(fv!item, "name"),
                                                                numberOfDocuments: fn!knowledgecenter(fv!item, "numberOfDocuments"),
                                                                sizeInKB: fn!round(fn!knowledgecenter(fv!item, "size")/1024,2),
                                                                sizeinMB: fn!round(fn!knowledgecenter(fv!item, "size") / 1024 / 1024, 2),
                                                                createdBy: fn!knowledgecenter(fv!item, "creator")
                                                                
                                                              }
                                                              
                                                            ),
                                                            local!output
                                                            
                                                            
                                                            
                                                          )

                                                          19 replies

                                                          stefanhelzle0001
                                                          Brainy
                                                          October 17, 2023

                                                          I don't think there is a solution for this. The plugin "Get All Knowledge Centers" is not available anymore.

                                                          uelm
                                                          uelmAuthor
                                                          October 17, 2023

                                                          Thanks for the reply, Stefan.

                                                          How would you tackle this (as I know you have a wealth of experience from other Community answers you've given)? Manually?

                                                          mikes0011
                                                          Brainy
                                                          October 17, 2023

                                                          I'm afraid it's a long, frustrating and almost completely manual process.  I have repeatedly begged Appian to provide better tools for gaining insight into top-level folders with relative sizes, and it has never materialized.  I faced this issue last year and had to build something custom to our setup.

                                                          stewart.burchell
                                                          October 18, 2023

                                                          It's not pretty and it is clunky but you can navigate to the "All Objects" view, filter by Folder and Search using "Knowledge Center" (assuming your KCs are all named this way):

                                                          You can then open the properties of each to get the contents/size value.

                                                          uelm
                                                          uelmAuthor
                                                          October 18, 2023

                                                          Thanks Stewart. Are there any plans in place to display folder sizes in an easier-to-view method? 

                                                          stewart.burchell
                                                          October 18, 2023

                                                          Sorry, I know of no such plans. In the meantime here's something I've cooked up. It relies on the Content Tools plug-in from the App Market:

                                                          a!localVariables(
                                                            local!ids: fn!enumerate(2000) + 1300,
                                                            local!contentObjects: a!forEach(
                                                              items: local!ids,
                                                              expression: fn!getcontentobjectdetailsbyid(fv!item)
                                                            ),
                                                            local!potentialKCs: a!forEach(
                                                              items: local!contentObjects,
                                                              expression: if(
                                                                fv!item = "No object with this ID has been found",
                                                                null,
                                                                fn!split(fv!item, ",")[5]
                                                              )
                                                            ),
                                                            local!KCIds: local!Ids[wherecontains(
                                                              " Type: Knowledge Center", local!potentialKCs
                                                            )],
                                                            a!forEach(
                                                              items: local!KCIds,
                                                              expression: fn!concat(
                                                                fn!knowledgecenter(fv!item, "name"),
                                                                ": ",
                                                                fn!round(fn!knowledgecenter(fv!item, "size")/1024,2),
                                                                "KB (",
                                                                "Number Of Documents: ",
                                                                fn!knowledgecenter(fv!item, "numberOfDocuments"),
                                                                ")"
                                                              )
                                                            )
                                                          )

                                                          Output for me is this:

                                                          You may have to adjust the starting point for where User-defined KCs come into play (I've set mine at 1300 in Line 2 of the code) and I've set my upper bound as 2000 above this which finds all the ones I can see in the All Objects view I posted about earlier.

                                                          srenj0001
                                                          Participating Frequently
                                                          October 8, 2024

                                                          I do it the following way. Notice that I use plugin "Content Tools":

                                                          a!localVariables(
                                                            folders: fn!findcontentbyattribute(
                                                              searchAllContent: true,
                                                              contentType: "folder",
                                                              attributeName: "name",
                                                              searchCriteria: "*"
                                                            ),
                                                            kcIds: a!forEach(
                                                              local!folders,
                                                              if(
                                                                isnull(fn!folder(fv!item, "parentFolderId")),
                                                                fn!folder(fv!item, "knowledgeCenterId"),
                                                                {}
                                                              )
                                                            ),
                                                            kcIds2: reject(fn!isnull, local!kcIds),
                                                            kcIds3: rule!BK_RemoveDuplicates(local!kcIds2),
                                                            kcMaps: a!forEach(
                                                              local!kcIds3,
                                                              a!map(
                                                                id: fv!item,
                                                                name: knowledgecenter(fv!item, "name"),
                                                                numberOfDocuments: knowledgecenter(fv!item, "numberOfDocuments"),
                                                                type: knowledgecenter(fv!item, "type"),
                                                                size: knowledgecenter(fv!item, "size")
                                                              )
                                                            ),
                                                            a!forEach(
                                                              local!kcMaps,
                                                              if(
                                                                or(
                                                                  fv!item.numberOfDocuments = 0,
                                                                  fv!item.type = 2/* Personal */
                                                                  
                                                                ),
                                                                {},
                                                                fv!item
                                                              )
                                                            )
                                                          )

                                                          I also use a function 'BK_RemoveDuplicates', that would be nice to have in the standard Appian repertoire:

                                                          /* The trick here is to use the union function: 
                                                          Apart from merging two (or more) lists, it also removes 
                                                          duplicates from the resulting list. */
                                                          
                                                          union(
                                                            cast(typeof(ri!list), {}), /* empty list */
                                                            ri!list
                                                          )

                                                          Input 'list' is Any Type.

                                                          mikes0011
                                                          Brainy
                                                          October 8, 2024

                                                          This looks good though I'd caution that in a production environment it might not be performant (at least in cases where there might be thousands or tens of thousands of procedurally generated subfolders i.e. in a personnel folder hierarchy).  When I tried it, it sat "thinking" for 5 minutes then returned an error.  Luckily it didn't do anything worse than that [emoticon:c4563cd7d5574777a71c318021cbbcc8]