jira-search
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJira Search Skill
Jira 搜索技能
Purpose
用途
Search for issues using JQL (Jira Query Language). Supports filtering, pagination, and field selection.
使用JQL(Jira查询语言)搜索问题。支持筛选、分页和字段选择。
When to Use
适用场景
- Searching issues by project, status, assignee, date
- Building issue lists and reports
- Finding specific issues by criteria
- Bulk operations on filtered issues
- 按项目、状态、经办人、日期搜索问题
- 生成问题列表和报表
- 根据条件查找特定问题
- 对筛选后的问题执行批量操作
Prerequisites
前置条件
- Authenticated JiraClient (see jira-auth skill)
- Project access permissions
- 已认证的JiraClient(参考jira-auth技能)
- 项目访问权限
Implementation Pattern
实现模式
Step 1: Define Search Types
步骤1:定义搜索类型
typescript
interface SearchOptions {
jql: string;
startAt?: number;
maxResults?: number;
fields?: string[];
expand?: string[];
}
interface SearchResponse {
startAt: number;
maxResults: number;
total: number;
issues: JiraIssue[];
}typescript
interface SearchOptions {
jql: string;
startAt?: number;
maxResults?: number;
fields?: string[];
expand?: string[];
}
interface SearchResponse {
startAt: number;
maxResults: number;
total: number;
issues: JiraIssue[];
}Step 2: Basic Search
步骤2:基础搜索
typescript
async function searchIssues(
client: JiraClient,
options: SearchOptions
): Promise<SearchResponse> {
return client.request<SearchResponse>('/search', {
method: 'POST',
body: JSON.stringify({
jql: options.jql,
startAt: options.startAt ?? 0,
maxResults: options.maxResults ?? 50,
fields: options.fields ?? ['key', 'summary', 'status', 'assignee', 'created'],
expand: options.expand,
}),
});
}typescript
async function searchIssues(
client: JiraClient,
options: SearchOptions
): Promise<SearchResponse> {
return client.request<SearchResponse>('/search', {
method: 'POST',
body: JSON.stringify({
jql: options.jql,
startAt: options.startAt ?? 0,
maxResults: options.maxResults ?? 50,
fields: options.fields ?? ['key', 'summary', 'status', 'assignee', 'created'],
expand: options.expand,
}),
});
}Step 3: Search All (Paginated)
步骤3:全量搜索(分页)
typescript
async function searchAllIssues(
client: JiraClient,
jql: string,
fields: string[] = ['key', 'summary', 'status']
): Promise<JiraIssue[]> {
const allIssues: JiraIssue[] = [];
let startAt = 0;
const maxResults = 100;
while (true) {
const response = await searchIssues(client, {
jql,
startAt,
maxResults,
fields,
});
allIssues.push(...response.issues);
if (startAt + response.issues.length >= response.total) {
break;
}
startAt += maxResults;
}
return allIssues;
}typescript
async function searchAllIssues(
client: JiraClient,
jql: string,
fields: string[] = ['key', 'summary', 'status']
): Promise<JiraIssue[]> {
const allIssues: JiraIssue[] = [];
let startAt = 0;
const maxResults = 100;
while (true) {
const response = await searchIssues(client, {
jql,
startAt,
maxResults,
fields,
});
allIssues.push(...response.issues);
if (startAt + response.issues.length >= response.total) {
break;
}
startAt += maxResults;
}
return allIssues;
}Step 4: Common Search Builders
步骤4:常用搜索构建器
typescript
// Search by project
function searchByProject(projectKey: string): string {
return `project = ${projectKey}`;
}
// Search by status
function searchByStatus(status: string | string[]): string {
if (Array.isArray(status)) {
return `status IN (${status.map(s => `'${s}'`).join(', ')})`;
}
return `status = '${status}'`;
}
// Search by assignee
function searchByAssignee(accountId: string): string {
return `assignee = '${accountId}'`;
}
// Search my issues
function searchMyIssues(): string {
return `assignee = currentUser()`;
}
// Search by date range
function searchByCreatedDate(daysAgo: number): string {
return `created >= -${daysAgo}d`;
}
// Combine conditions
function combineJql(...conditions: string[]): string {
return conditions.join(' AND ');
}typescript
// Search by project
function searchByProject(projectKey: string): string {
return `project = ${projectKey}`;
}
// Search by status
function searchByStatus(status: string | string[]): string {
if (Array.isArray(status)) {
return `status IN (${status.map(s => `'${s}'`).join(', ')})`;
}
return `status = '${status}'`;
}
// Search by assignee
function searchByAssignee(accountId: string): string {
return `assignee = '${accountId}'`;
}
// Search my issues
function searchMyIssues(): string {
return `assignee = currentUser()`;
}
// Search by date range
function searchByCreatedDate(daysAgo: number): string {
return `created >= -${daysAgo}d`;
}
// Combine conditions
function combineJql(...conditions: string[]): string {
return conditions.join(' AND ');
}Step 5: Advanced Search Examples
步骤5:高级搜索示例
typescript
// Find all open issues in project
async function findOpenIssues(client: JiraClient, projectKey: string) {
return searchAllIssues(
client,
combineJql(
searchByProject(projectKey),
`status NOT IN (Done, Closed)`
)
);
}
// Find my recent issues
async function findMyRecentIssues(client: JiraClient, daysAgo: number = 7) {
return searchAllIssues(
client,
combineJql(
searchMyIssues(),
searchByCreatedDate(daysAgo)
)
);
}
// Find issues by label
async function findByLabel(client: JiraClient, projectKey: string, label: string) {
return searchAllIssues(
client,
combineJql(
searchByProject(projectKey),
`labels = '${label}'`
)
);
}
// Find unassigned issues
async function findUnassigned(client: JiraClient, projectKey: string) {
return searchAllIssues(
client,
combineJql(
searchByProject(projectKey),
`assignee IS EMPTY`
)
);
}typescript
// Find all open issues in project
async function findOpenIssues(client: JiraClient, projectKey: string) {
return searchAllIssues(
client,
combineJql(
searchByProject(projectKey),
`status NOT IN (Done, Closed)`
)
);
}
// Find my recent issues
async function findMyRecentIssues(client: JiraClient, daysAgo: number = 7) {
return searchAllIssues(
client,
combineJql(
searchMyIssues(),
searchByCreatedDate(daysAgo)
)
);
}
// Find issues by label
async function findByLabel(client: JiraClient, projectKey: string, label: string) {
return searchAllIssues(
client,
combineJql(
searchByProject(projectKey),
`labels = '${label}'`
)
);
}
// Find unassigned issues
async function findUnassigned(client: JiraClient, projectKey: string) {
return searchAllIssues(
client,
combineJql(
searchByProject(projectKey),
`assignee IS EMPTY`
)
);
}JQL Quick Reference
JQL 快速参考
Operators
运算符
| Operator | Example | Description |
|---|---|---|
| | Equals |
| | Not equals |
| | One of |
| | Not one of |
| | Contains |
| | Is null |
| | Is not null |
| | Greater/equal |
| | Less/equal |
| 运算符 | 示例 | 说明 |
|---|---|---|
| | 等于 |
| | 不等于 |
| | 属于 |
| | 不属于 |
| | 包含 |
| | 为空 |
| | 不为空 |
| | 大于等于 |
| | 小于等于 |
Date Formats
日期格式
| Format | Example | Description |
|---|---|---|
| Relative | | 7 days ago |
| Relative | | 2 weeks ago |
| Relative | | 1 month ago |
| Absolute | | Specific date |
| Function | | Today midnight |
| Function | | Monday |
| 格式 | 示例 | 说明 |
|---|---|---|
| 相对日期 | | 7天前 |
| 相对日期 | | 2周前 |
| 相对日期 | | 1个月前 |
| 绝对日期 | | 特定日期 |
| 函数 | | 今日午夜 |
| 函数 | | 周一 |
Common JQL Patterns
常用JQL模式
jql
undefinedjql
undefinedAll issues in project
All issues in project
project = SCRUM
project = SCRUM
Open issues
Open issues
project = SCRUM AND status != Done
project = SCRUM AND status != Done
My issues
My issues
assignee = currentUser()
assignee = currentUser()
High priority open issues
High priority open issues
project = SCRUM AND priority = High AND status != Done
project = SCRUM AND priority = High AND status != Done
Created this week
Created this week
project = SCRUM AND created >= startOfWeek()
project = SCRUM AND created >= startOfWeek()
Updated recently
Updated recently
project = SCRUM AND updated >= -7d
project = SCRUM AND updated >= -7d
Unassigned bugs
Unassigned bugs
project = SCRUM AND issuetype = Bug AND assignee IS EMPTY
project = SCRUM AND issuetype = Bug AND assignee IS EMPTY
Issues with specific label
Issues with specific label
project = SCRUM AND labels = "urgent"
project = SCRUM AND labels = "urgent"
Text search in summary
Text search in summary
project = SCRUM AND summary ~ "authentication"
undefinedproject = SCRUM AND summary ~ "authentication"
undefinedcurl Examples
curl 示例
Basic Search
基础搜索
bash
curl -X POST "$JIRA_BASE_URL/rest/api/3/search" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{
"jql": "project = SCRUM AND status != Done",
"startAt": 0,
"maxResults": 50,
"fields": ["key", "summary", "status", "assignee"]
}'bash
curl -X POST "$JIRA_BASE_URL/rest/api/3/search" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{
"jql": "project = SCRUM AND status != Done",
"startAt": 0,
"maxResults": 50,
"fields": ["key", "summary", "status", "assignee"]
}'Search with Pagination
分页搜索
bash
curl -X POST "$JIRA_BASE_URL/rest/api/3/search" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{
"jql": "project = SCRUM",
"startAt": 50,
"maxResults": 50,
"fields": ["key", "summary"]
}'bash
curl -X POST "$JIRA_BASE_URL/rest/api/3/search" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{
"jql": "project = SCRUM",
"startAt": 50,
"maxResults": 50,
"fields": ["key", "summary"]
}'Search with Changelog Expand
包含变更日志的搜索
bash
curl -X POST "$JIRA_BASE_URL/rest/api/3/search" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{
"jql": "project = SCRUM AND updated >= -7d",
"maxResults": 50,
"fields": ["key", "summary", "status"],
"expand": ["changelog"]
}'bash
curl -X POST "$JIRA_BASE_URL/rest/api/3/search" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{
"jql": "project = SCRUM AND updated >= -7d",
"maxResults": 50,
"fields": ["key", "summary", "status"],
"expand": ["changelog"]
}'Response Structure
响应结构
json
{
"startAt": 0,
"maxResults": 50,
"total": 150,
"issues": [
{
"id": "10001",
"key": "SCRUM-1",
"self": "$JIRA_BASE_URL/rest/api/3/issue/10001",
"fields": {
"summary": "Issue summary",
"status": { "name": "To Do" },
"assignee": { "displayName": "John Doe" }
}
}
]
}json
{
"startAt": 0,
"maxResults": 50,
"total": 150,
"issues": [
{
"id": "10001",
"key": "SCRUM-1",
"self": "$JIRA_BASE_URL/rest/api/3/issue/10001",
"fields": {
"summary": "Issue summary",
"status": { "name": "To Do" },
"assignee": { "displayName": "John Doe" }
}
}
]
}Pagination Formula
分页公式
Total pages = ceil(total / maxResults)
Current page = floor(startAt / maxResults) + 1
Has more = (startAt + issues.length) < total
Next startAt = startAt + maxResultsTotal pages = ceil(total / maxResults)
Current page = floor(startAt / maxResults) + 1
Has more = (startAt + issues.length) < total
Next startAt = startAt + maxResultsCommon Mistakes
常见错误
- Not quoting status values with spaces
- Using email instead of accountId for assignee
- Forgetting pagination for large result sets
- Not escaping special characters in search text
- 未给包含空格的状态值添加引号
- 使用邮箱而非accountId指定经办人
- 处理大量结果集时忘记分页
- 未对搜索文本中的特殊字符进行转义
References
参考链接
Version History
版本历史
- 2025-12-10: Created
- 2025-12-10: 创建