JQL

Mẹo tìm kiếm issue Jira cho Product Manager

Jira Software đã trở thành một công cụ theo dõi ticket phổ biến và được ưa chuộng bởi cộng đồng Product Manager. Có thể nói, Jira Software là một công cụ có khả năng tùy chỉnh cực kì mạnh mẽ, do vậy có rất nhiều tính năng mà Jira user có thể chưa sử dụng nhiều, trong đó có JQL. 

Điểm qua một chút về JQL

JQL là viết tắt của Jira Query Language. Về cơ bản, JQL khá giống SQL, chỉ khác là JQL dành riêng Jira mà thôi. Đây là một công cụ linh hoạt và giúp chúng ta có thể tìm kiếm một Jira ticket nhanh hơn. (Lưu ý, khái niệm ticket ở trong Jira tương đồng với issue).

Tại sao cần truy vấn Jira ticket? 

Chúng ta thử xem xét 1 ví dụ sau. Đây là ví dụ ticket các loại việc mà tôi phải làm với tư cách là một Product Manager:

  • Xác định tất cả các bug trước đó
  • Tìm kiếm những sprint có nhiều bug hơn bình thường
  • Tạo báo cáo ticket các loại công việc khác nhau mà team đã giải quyết trong quý trước
  • Tìm ticket mà team quan tâm nhất
  • Xác định xem liệu một người có là dư thừa trong nhiều sprint trong quá khứ hay không

Nếu không có khả năng truy vấn Jira ticket, sẽ khó khăn hơn khi biên soạn thông tin cần thiết.

Đây là giao diện để có thể truy cập JQL, giao diện này mạnh hơn nhiều so với các bộ lọc default của Jira. Trong chế độ “Browse” cho ticket, nhấp vào “Advanced” và thanh truy vấn nâng cao sẽ xuất hiện. Bạn có thể tìm thấy một ví dụ tại https://jira.atlassian.com/browse/JSWCLOUD-17214?filter=98153.

Một vấn đề nho nhỏ – hiện tại có rất nhiều tài liệu về JQL. Nhưng tôi chưa thấy có hướng dẫn về truy vấn nào là hữu ích nhất và cách xây dựng dựa trên kiến ​​thức có sẵn từ SQL.

Truy vấn Jira

Vì vậy, đây là 14 truy vấn Jira phổ biến, giúp chúng ta có thể nhanh chóng lấy được ticket mà mình cần. Đối với mỗi truy vấn, tôi sẽ hướng dẫn chi tiết chức năng của nó, cách cải tiến và cách đưa nó vào quy trình product management hàng ngày của bạn.

  1. assignee = Thuan
  2. assignee was Thuan
  3. reporter = Thuan
  4. watcher = Thuan
  5. text ~ “form submission”
  6. project = “Atlassian”
  7. issueType = bug
  8. order by priority desc
  9. order by created desc
  10. order by resolutiondate desc
  11. status in (“open”, “in progress”)
  12. status not in (“blocked”, “closed”)
  13. sprint is empty

Cùng đi sâu hơn vào từng truy vấn bên dưới.

hướng dẫn JQL

1) assignee = Thuan

Tôi cần tìm kiếm các ticket mà tôi là assignee. Khi đó, tôi sẽ viết truy vấn JQL “assignee = Thuan” để tìm kiếm.

Cái này hoạt động ra sao?

“assignee” là một field (nôm na là 1 trường thông tin) và trường này nằm trong mỗi ticket Jira mà bạn có.

Từ thứ hai “=” là một toán tử và chúng ta sẽ sử dụng các toán tử để cho Jira biết loại phương trình mà chúng ta đang cố gắng xây dựng.

Từ thứ ba “Thuan” là một giá trị và chúng ta sử dụng các giá trị để cho Jira biết những gì chúng ta đang tìm kiếm.

Vì vậy, “assignee = Thuan” đang yêu cầu Jira xem xét trường “assignee” của tất cả các ticket trước, sau đó kiểm tra xem liệu bất kỳ người nào trong số assignee đó có phải là “Thuan” (đó là tên người dùng Jira của tôi) hay không.

Tất nhiên, biết cách tự tìm ticket là chưa đủ. Chúng ta cũng có thể muốn xem các ticket được giao cho người khác. Chúng ta làm điều đó như thế nào?

Giả sử rằng tôi muốn tìm kiếm những tấm ticket được giao cho Thu, đồng nghiệp của tôi. Khi đó, tôi sẽ thay đổi truy vấn JQL thành “assignee = Thu”. Khá là đơn giản.

Tôi có thể sử dụng truy vấn assignee để xác định xem một trong những thành viên trong team có bị quá tải công việc hay không. Nếu có, tôi sẽ nhanh chóng giao lại cho người khác và đảm bảo rằng chúng tôi đang phân phối công việc đồng đều.

Nhưng, có một sự thay đổi. Vấn đề với dấu “=” là nó chỉ kiểm tra trạng thái hiện tại của mỗi ticket. Nếu tôi cần nhìn lại quá khứ thì sao?

Ví dụ: đối với một số Jira board mà tôi là thành viên, assignee trước tiên bắt đầu với product manager, sau đó là engineer, sau đó là analyst. Sau đó, khi ticket đã vượt qua các test case và được chuyển vào giai đoạn sản xuất, ticket sẽ tự động đổi trạng thái là unassigned. 

Nếu tôi muốn biết các ticket mà Huy đã hoàn thành, tôi không thể nhận các ticket đó với “assignee = Huy” – do các ticket đã hoàn thành đều có trường assignee là unassigned.

Vì vậy, hãy sử dụng “was” để thay thế.

Ví dụ: truy vấn Jira có thể là “assignee was Huy” -> Truy vấn này sẽ xuất ra tất cả các ticket đã từng hoặc đang có giá trị trường assignee là Huy.

2) Assignee was Thuan

Tôi là một người rất thích sử dụng “was”. Nếu tôi sử dụng truy vấn “assignee was Thuan”, tôi có thể thấy từng ticket đã được chỉ định cho tôi – ngay cả khi tôi không còn được chỉ định cho ticket đó nữa.

Điều tuyệt vời ticket toán tử “was” là nó cũng bao gồm cả hiện tại. Vì vậy, nếu tôi là assignee cho ticket ATL-123 hiện tại, thì truy vấn “assignee was Thuan” sẽ vẫn cung cấp cho tôi ATL-123 trong kết quả của nó.

Nhưng còn việc xử lý những tấm ticket đã lọt qua kẽ hở và hoàn toàn là unassigned thì sao?

3) Assignee is Empty

Trong truy vấn này, chúng ta đang tìm hiểu hai khái niệm mới cùng một lúc. Đầu tiên, chúng ta giải quyết toán tử “is”; nó khá giống với SQL tương đương của nó.

Trong SQL, nếu bạn đang tìm kiếm trạng thái của một trường, bạn đang không sử dụng cú pháp “assignee = NULL”. Thay vào đó, bạn sử dụng cú pháp “assignee IS NULL”, vì NULL không phải là một giá trị. 

4) reporter = Thuan

Được rồi, những điều này vẫn còn một chút hạn chế. Tôi vẫn chưa thể tìm kiếm bất cứ điều gì bên ngoài “assignee”. Nếu tôi muốn tìm kiếm chi tiết hơn thì sao? Ví dụ: giả sử sếp của tôi đã báo cáo một bug và tôi không biết đó là bug nào. Tôi sẽ lấy thông tin đó bằng cách nào?

Rất may, Jira có một trường gọi là “reporter”, theo dõi ai đã tạo ra ticket ngay từ đầu.

Vì vậy, nếu tôi đang tìm kiếm các ticket mà sếp của tôi, Huân đã tạo, tôi có thể viết truy vấn JQL “report = Huan” để tìm các lỗi mà anh ấy đã báo cáo.

Tuy nhiên, hãy nói rằng điều đó là chưa đủ. Điều gì sẽ xảy ra nếu tôi cần tìm những ticket mà sếp của tôi là reporter, đồng thời tìm những ticket chưa có assignee?

Tôi có thể thêm từ khóa “AND” vào JQL và bây giờ tôi có thể xem xét hai thứ cùng một lúc.

Nếu tôi viết JQL “reporter = Huan AND assignee is empty”, bây giờ tôi nhận được tất cả các ticket mà sếp của tôi là reporter, nhưng chỉ khi không có ai được chỉ định cho ticket đó.

Vì vậy, tôi có thể sử dụng tính năng này để nhanh chóng kiểm tra xem liệu các ticket mà sếp quan tâm đã được giao cho ai chưa. 

5) Watcher = Thuan

Sếp của tôi không thường xuyên gửi ticket cho Jira. Sếp thường chỉ subscribe các ticket mà anh ấy đặc biệt quan tâm, chẳng hạn như các ticket có ảnh hưởng đến khách hàng.

Trong Jira, bạn có khả năng xem ticket. Khi bạn xem một ticket, bạn sẽ nhận được thông báo trong email của mình; bạn sẽ được thông báo ticket các thay đổi status, comment và thậm chí là các thay đổi trong description của ticket.

Tuy nhiên, có một lưu ý – Reporter không nhất thiết phải là watcher và watcher không nhất thiết phải là reporter.

Vì vậy, bây giờ tôi sẽ sử dụng từ khóa “OR” để kiểm tra trên cả hai trường. Nếu tôi sử dụng truy vấn JQL “report = Huan hoặc watcher = Huan”, bây giờ tôi có thể theo dõi tất cả các ticket mà sếp của tôi đã submit và tất cả các ticket mà team lead của tôi đang xem.

Nhưng giả sử rằng tôi vẫn quan tâm đến việc đảm bảo rằng tôi chỉ nhận được những ticket không có assignee. Khi đó, tôi sẽ cần thêm 1 số cụm khác trong truy vấn.

Bây giờ chúng ta sẽ thêm “()” để nhóm logic lại với nhau.

Vì vậy, bây giờ tôi sẽ viết “(report = Huan OR watcher = Huan) AND assignee is empty” làm truy vấn của mình.

Tại sao tôi làm điều đó? Nếu tôi đặt “OR” không đúng chỗ, truy vấn sẽ trả về kết quả sai. Ví dụ: nếu tôi đã viết “reporter = Huan AND assignee is empty OR Watcher = Huan”, thì tôi sẽ nhận được tất cả các ticket mà sếp của tôi đang xem, bất kể ticket đó là gì.

6) Text ~ “Form Submission”

Nếu tôi đang tìm kiếm một ticket cụ thể thì sao? Ví dụ: giả sử rằng tôi nhận được một số báo cáo bug mới trong đó một trong các trang web gặp sự cố do lỗi trong quá trình gửi biểu mẫu. Tôi đang cố gắng tìm ra các ticket trước đây đã giải quyết một vấn đề tương tự như thế này, để tôi có thể thu hẹp nguyên nhân gốc rễ của vấn đề.

Bạn có thể sử dụng truy vấn “Text ~ “Form Submission” để tìm kiếm bất kỳ ticket nào liên quan đến việc gửi biểu mẫu. Jira sẽ xem xét cả tiêu đề của ticket cũng như mô tả của ticket.

Lưu ý rằng nếu bạn muốn giới hạn mình chỉ tìm kiếm trong các nhận xét, thì bạn có thể sử dụng “comment ~ “form submission“” và nếu bạn muốn giới hạn chỉ trong phần description, thì bạn có thể sử dụng “description ~ “form submission””. Ngoài ra, nếu bạn muốn tìm kiếm tên của ticket, hãy sử dụng “summary ~ “form submission””, vì Jira gọi nó là summary.

Được rồi, nhưng “~” là gì?

Về cơ bản, ~ trong Jira chính là từ “contain” trong tiếng Anh, tôi dịch nó là “bao gồm”. 

7) Project = “Atlassian”

Hãy sử dụng từ khóa “project” để tìm kiếm các dự án cụ thể mà tôi quan tâm!

Giả sử tôi có hai dự án, Atlassian và Atlassian events. Tôi sẽ cần dùng từ khóa “project” làm bộ lọc để tôi không bị nhầm lẫn ticket loại ticket mà mình đang xem.

Vì vậy, tôi có thể tìm “Project = “Atlassian” AND assignee is empty” để nhanh chóng tìm kiếm các ticket trong project Atlassian mà không có ai được chỉ định.

8) IssueType = Bug

Sản phẩm nào cũng có bug, 100%. Cần làm gì khi chúng ta muốn biết tất cả các bug nằm trong sản phẩm cụ thể nào đó?

Tôi có thể sử dụng từ khóa “issueType” để tìm bug. Vì vậy, nếu tôi viết “project = “Atlassian” AND issueType = bug”, tôi có thể tìm kiếm tất cả các lỗi liên quan đến project “Atlassian”.

Tôi cũng có thể sử dụng các loại issueTypes khác nhau, chẳng hạn như story, task và epic. Ví dụ: nếu tôi muốn biết ticket tất cả các epic có trong project Atlassian, tôi có thể nhập “project = “Atlassian” AND issueType = epic” để tìm câu trả lời.

Được rồi, quay lại bug. Tôi thực sự muốn biết ticket những bug critical nhất trước tiên. Làm cách nào để sắp xếp kết quả mà tôi nhận lại?

9) Order by Priority Desc

Bây giờ, chúng ta sẽ sử dụng cụm “order by” để nói với Jira rằng chúng ta muốn kết quả của chúng tôi được sắp xếp theo một cách cụ thể. Ở đây, tôi đang sắp xếp theo trường “priority” trong Jira. Tại nơi làm việc, ticket của chúng ta có 5 ưu tiên khác nhau:

P0 = blocker

P1 = critical

P2 = major

P3 = minor

P4 = trivial

Nhưng “desc” là gì? Đây là viết tắt của từ “descendant” có nghĩa là từ dưới lên. Điều đó cho Jira biết tôi muốn sắp xếp của mình như thế nào. Bạn chỉ có hai tùy chọn ở đây: “desc” và “asc”. Đối lập với desc, asc (ascentdant) sẽ sắp xếp theo thứ tự từ trên xuống (từ issue lớn nhất hoặc mới nhất xuống dưới). Điều đó thực sự khá hay, bởi vì nếu tôi chọn sai thứ tự, tôi có thể thay đổi thứ tự nhanh chóng.

Vì vậy, bây giờ tôi sẽ tìm kiếm “project = “Atlassian” AND issueType = bug order by priority desc”, và truy vấn sẽ trả về cho tôi tất cả các bug trong project Atlassian, được sắp xếp theo mức độ ưu tiên cao nhất trước.

10) Order by Created Desc

Bây giờ, giả sử rằng tôi đang tìm kiếm các bug đã được submit cách đây một thời gian. Nếu chúng tôi vẫn chưa giải quyết được những bug đó, thì đó có thể là vấn đề lớn.

Tôi có thể sắp xếp theo từ “created” để tìm ticket đã tồn tại được một thời gian. Và, tôi có thể kết hợp điều này cùng với “Order by Created Desc” khác của mình để trước tiên tôi xem xét các lỗi có mức độ ưu tiên cao nhất, sau đó xem nó đã được tạo ra bao lâu rồi.

Đây là truy vấn bây giờ: “project = “Atlassian” and issueType = bug order by priority desc, created asc”

Hãy chú ý cách tôi đã sử dụng dấu phẩy giữa hai mệnh đề “order by”. Đầu tiên nó sẽ sắp xếp tất cả các ticket theo thứ tự ưu tiên, vì vậy tất cả các ticket P0 sẽ đi cùng nhau, tất cả các ticket P1 sẽ lần lượt ngay sau, v.v.

Sau đó, nó sắp xếp thứ tự theo ngày nó được tạo, nhưng chỉ trong loại đầu tiên. Vì vậy, tôi sẽ thấy P0 cũ nhất của mình, sau đó là P0 mới hơn, sau đó là P0 mới hơn, v.v., chỉ cho đến khi tôi hết ticket P0. Sau đó, tôi sẽ thấy P1 cũ nhất, rồi P1 mới hơn, rồi P1 mới hơn, v.v., cho đến khi tôi hết ticket P1.

11) Order by Resolutiondate Desc

Được rồi, tôi đã có ngày tạo bug. Nhưng làm thế nào để biết liệu nó đã được fix hay chưa?

Một cách để giải quyết vấn đề đó là sử dụng “ Order by Resolutiondate Desc”, để tôi có thể xem các ticket đã được giải quyết gần đây. Ví dụ: bây giờ tôi có thể nói “project = “Atlassian” AND issueType = bug order by priority desc, Resolutionutiondate desc” để tìm các lỗi có mức độ ưu tiên cao nhất có ngày giải quyết gần đây nhất.

12) Status in (“Open”, “in Progress”)

Điều gì sẽ xảy ra nếu tôi đang cố gắng xem liệu một bug có được xử lý hay không? Tôi có thể sử dụng “status” để tìm nó. Trong Jira, bạn sẽ có các status ticket khác nhau – hãy kiểm tra xem bạn hiện đang sử dụng status nào trong dự án của mình.

Đối với dự án Atlassian của tôi, chỉ có 4 status: open, in progress, blocked, và closed.

Vì vậy, bây giờ tôi có thể tìm kiếm các bug đang ở status “open” hoặc “in progress”. Tôi có thể làm điều đó bằng cách sử dụng “in” để chọn nhiều tùy chọn cùng một lúc, thay vì phải viết một loạt các câu lệnh “OR”.

Truy vấn bây giờ trông giống như sau: “project = “Atlassian” and issueType = bug and status in (“ open ”,“ in process ”)”

Truy vấn sẽ trả về tất cả các bug trong dự án Atlassian và chỉ giới hạn trong status đang open hoặc in progress.

13) Status not in (“Blocked”, “Closed”)

Nhưng, nếu tôi có quá nhiều status thì sao? Ví dụ: điều gì sẽ xảy ra nếu tôi có 15 status khác nhau, tất cả đều có thể quy ra là “đang xử lý” hoặc đang làm và tôi chỉ muốn tìm kiếm các ticket không bị block hoặc bị đóng?

Tôi có thể làm điều đó bằng cách sử dụng “NOT”, như thế này: “project = “Atlassian” and issueType = bug and status not in (“ block, ”closed”) ”.

Trong một project mà tôi chỉ có bốn status mà tôi đã đề cập, điều này có chức năng giống như status mà tôi đã nói “project = NEWPROJ và issueType = bug and status in (“ open ”,” in process ”)”. Nhưng trong các dự án mà tôi có nhiều status tôi có thể sử dụng “not in” để làm nó dễ dàng hơn.

14) Sprint is Empty

Được rồi, cái cuối cùng. Tôi cần tìm những bug trong Atlassian chưa được phân bổ cho sprint, để tôi có thể quyết định cái nào sẽ chuyển sang sprint.

JQL sử dụng khái niệm “EMPTY” để tìm những trường không có giá trị.” Ví dụ: “sprint IS EMPTY” có nghĩa là một ticket không thuộc ticket sprint nào.

Vì vậy, truy vấn cuối cùng của tôi là “project = “Atlassian” and issueType = bug and status in (“ open ”,“ in process ”) and sprint is empty” để tìm kiếm tất cả các ticket mà tôi có thể cần để chuyển sang sprint.

Tạm Kết 

Bằng cách đầu tư thời gian vào việc tìm hiểu đầy đủ các công cụ mà bạn sử dụng hàng ngày, bạn sẽ không chỉ làm việc hiệu quả hơn mà còn mở khóa các khả năng mới mà bạn không biết là mình có.

Bằng cách dành thời gian tìm hiểu ticket JQL, bạn sẽ có thể cập nhật và sửa đổi ticket dễ dàng hơn nhiều.