如何在java/groovy中减少自定义API端点的输出



我正在改进Confluence Server平台的自定义搜索。我们有一个名为Scriptrunner的插件,它允许我们使用Groovy而不是Java来编写代码。

我正在处理的代码是一个搜索API端点,它目前运行良好,但返回了很多不必要的信息,甚至是重复的信息,所以我想以最有效的方式缩小搜索输出的范围。

该平台有一个javadoc,我正试图将其用于实现,链接:https://docs.atlassian.com/ConfluenceServer/javadoc/7.8.1/com/atlassian/confluence/search/v2/SearchManager.html

我想实现以下部分

search(ISearch search, Set<String> requestedFields)
Perform a search with a given criteria, the returns searchResults only have the fields requested in the projection filled out, no other fields are valid in the searchResult.

但我无法理解如何正确生成Set<String> requestedFields

以下是我的尝试:

import...
def searchManager = ComponentLocator.getComponent(SearchManager)
def paramQueryString = "ArticleThatWillBeDeleted"
def query = BooleanQuery.andQuery(new TextQuery(paramQueryString));
def sort = new RelevanceSort();
def searchFilter = SiteSearchPermissionsSearchFilter.getInstance();
def searchContent = new ContentSearch(query, sort, searchFilter, 0, 100);
Set<String> requestedFields = new HashSet<String>();
requestedFields.add("displayTitle");
def searchresult = searchManager.search(searchContent,requestedFields)
return searchresult.getAll()

如果我想使用其他方法

search(ISearch search)
Perform a search with a given criteria.

这个脚本运行得很好,但返回了很多我想删掉的信息。

除了我想要实现的方法之外,我还对任何其他类型的建议持开放态度,在这些建议中,我只能指定我想要输出的信息,这样我就可以安全地输出大小和处理能力。

第页。S我已经试着在他们的社区页面上详细地问过同样的问题,但我认为我可以在这方面得到一些开发人员的帮助,因为我刚刚从这方面学到了Java/Govy。

详细说明:https://community.atlassian.com/t5/Confluence-questions/Need-to-optimize-the-output-of-a-custom-Search-API-Endpoint-in/qaq-p/1515177

更新:

以下是作为API端点实现的工作代码:

import com.atlassian.seraph.auth.DefaultAuthenticator
import com.atlassian.confluence.user.UserAccessor
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator

import com.atlassian.confluence.search.service.ContentTypeEnum
import com.atlassian.confluence.search.v2.SearchManager
import com.atlassian.confluence.search.v2.searchfilter.SiteSearchPermissionsSearchFilter
import com.atlassian.confluence.search.v2.ContentSearch
import com.atlassian.confluence.search.v2.query.*
import com.atlassian.confluence.search.v2.sort.RelevanceSort
import com.atlassian.confluence.search.v2.SearchSort
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import org.codehaus.jackson.map.ObjectMapper
import java.util.HashSet
@BaseScript CustomEndpointDelegate delegate
testSearch(
    httpMethod: "GET", groups: ["access_group_1","access_group_2"]
) { MultivaluedMap queryParams, String body ->
    def searchManager = ComponentLocator.getComponent(SearchManager)
    // Query can be of any type noted here:
    //https://developer.atlassian.com/server/confluence/searching-using-the-v2-search-api/
    def paramQueryString = (queryParams.get(new String("q"))).get(0)
    def query = BooleanQuery.andQuery(new TextQuery(paramQueryString));
    def sort = new RelevanceSort();
    def searchFilter = SiteSearchPermissionsSearchFilter.getInstance();
    def searchContent = new ContentSearch(query, sort, searchFilter, 0, 100);
    def searchresult = searchManager.search(searchContent)
    return Response.ok(new JsonBuilder([results: searchresult.getAll()]).toString()).build()
}

当我调用API 时

http://10.10.10.11:8080/rest/scriptrunner/latest/custom/testSearch?q=ArticleThatWillBeDeleted

我得到以下JSON响应

{
    "results": [
        {
            "displayTitle": "ArticleThatWillBeDeleted",
            "handle": {
                "className": "com.atlassian.confluence.pages.Page",
                "id": 359071873
            },
            "lastUpdateDescription": "",
            "ownerTitle": null,
            "spaceName": "Employee Team Space",
            "creatorUser": {
                "backingUser": {
                    "active": true,
                    "lowerName": "vnikolov",
                    "directoryId": 142049281,
                    "fullName": "Vasil Nikolov",
                    "emailAddress": "vnikolov@domain.com",
                    "email": "vnikolov@domain.com",
                    "name": "vnikolov",
                    "displayName": "Vasil Nikolov"
                },
                "lowerName": "vnikolov",
                "key": {
                    "stringValue": "8a606c8c56a371040156a37301341285"
                },
                "fullName": "Vasil Nikolov",
                "email": "vnikolov@domain.com",
                "name": "vnikolov"
            },
            "resultExcerpt": "this is the body of the article that will be delted.",
            "ownerType": null,
            "lastModifier": "vnikolov",
            "urlPath": "/display/WIT/ArticleThatWillBeDeleted",
            "resultExcerptWithHighlights": "this is the body of the article that will be delted.",
            "explain": {
                "present": false,
                "empty": true
            },
            "lastModifierUser": {
                "backingUser": {
                    "active": true,
                    "lowerName": "vnikolov",
                    "directoryId": 142049281,
                    "fullName": "Vasil Nikolov",
                    "emailAddress": "vnikolov@domain.com",
                    "email": "vnikolov@domain.com",
                    "name": "vnikolov",
                    "displayName": "Vasil Nikolov"
                },
                "lowerName": "vnikolov",
                "key": {
                    "stringValue": "8a606c8c56a371040156a37301341285"
                },
                "fullName": "Vasil Nikolov",
                "email": "vnikolov@domain.com",
                "name": "vnikolov"
            },
            "extraFields": {
                "content-version": "1"
            },
            "lastModificationDate": "2020-10-20T20:42:27+0000",
            "type": "page",
            "content": "   nthis is the body of the article that will be delted.n ",
            "creationDate": "2020-10-20T20:41:46+0000",
            "personalLabels": [],
            "status": "current",
            "spaceKey": "WIT",
            "contentVersion": 1,
            "creator": "vnikolov",
            "displayTitleWithHighlights": "ArticleThatWillBeDeleted",
            "homePage": false,
            "sanitisedContent": "this is the body of the article that will be delted."
        }
    ]
}

我得到了4倍的身体(结果摘录,结果摘录有亮点,内容,消毒内容(我所需要的只是content,如果可能的话,可以将其缩小到有限的大小或字符长度。

当我尝试通过添加以下行来实现requestedFields并修改searchresult

    def requestedFields = [ 'content', 'displaytitle' ] as Set
    def searchresult = searchManager.search(searchContent,requestedFields)

我得到的JSON响应是:

{
    "results": [
        {
            "resultExcerpt": "",
            "explain": {
                "present": false,
                "empty": true
            },
            "resultExcerptWithHighlights": "",
            "extraFields": {},
            "displayTitleWithHighlights": ""
        }
    ]
}

我注意到的另一件事是,在工作示例中,返回的类是:com.atlassian.confluence.search.v2.lucene.LuceneSearchResult@1233a8a4并且在CCD_ 6尝试中,结果类是:com.atlassian.confluence.search.v2.ProjectedSearchResult@6c688cdd

我想找到一种方法来控制API的输出,它不必是我试图实现的requestedFields方法。

JsonBuilder呈现所有对象属性,而不仅仅是您从服务器请求的字段。

我看到的呈现请求字段的最简单方法:

def requestedFields = [ 'content', 'displaytitle' ] as Set
def searchresult = searchManager.search(searchContent,requestedFields)
def table = searchresult.getAll().collect{row-> 
    requestedFields.collectEntries{fldName->  
        [ fldName , row.getField(fldName) ] 
    }
}
    
def json = new groovy.json.JsonBuilder(table).toPrettyString()
Response.ok(json).build()

最新更新