资讯动态

Beads `bd query` 实战指南:用布尔表达式查询语言精准检索 Issue

发布时间:2026/9/12 16:10:24 来源:尧图企业网站定制
Beadsbd query实战指南用布尔表达式查询语言精准检索 Issue【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads导读bd query是 Beads 内置的 Issue 查询命令它提供了一套自带词法分析器lexer、解析器parser与求值器evaluator的布尔表达式查询语言支持字段比较、AND/OR/NOT逻辑运算、括号分组、相对日期与自然语言日期表达。借助它你可以用一条命令完成原本需要多个过滤参数或jq管道才能实现的复杂筛选。读完本文你将掌握查询语言的完整语法、全部可查询字段与取值约束、日期表达方式、命令行参数语义并能理解其存储层下推 内存谓词求值的双轨执行原理与边界行为。一、命令概览与使用场景bd query由 cmd/bd/query.go 实现注册在issues命令组下基本调用形式为bd query [expression] [flags]它解决的问题很直接当你在 Beads 工作区里积累了大量 Issue 后简单的bd list加过滤参数难以表达打开状态、优先级不低于 2、且 7 天内更新过这类组合条件更无法表达bug 类型或 urgent 标签这种或关系。bd query用一条表达式即可覆盖这些场景bd query statusopen AND priority1 AND updated7d bd query typebug OR labelurgent命令入口的完整流程见 cmd/bd/query.go为收集输入 →可选仅解析并打印 AST → 打开 Querier 角色 → 执行查询 → 按文本或 JSON 输出结果并在 stderr 打印截断提示。与bd list不同的是查询表达式的解析、求值以及如何执行全部封装在issueops.Querier角色内部CLI 层只负责传递表达式原文见 issueops/querier.go。二、查询语言语法全解2.1 比较运算符语法定义位于命令帮助与 internal/query/lexer.go 的词法实现中支持六种运算符运算符含义示例相等statusopen!不相等status!closed大于priority1大于等于priority2小于priority2小于等于priority2需要注意的是并非所有字段都支持全部运算符。求值器internal/query/evaluator.go对每个字段做了白名单校验例如status只支持与!label、title、description等文本字段只支持而priority、时间类字段支持完整的比较集合。使用不支持的操作符会得到明确的校验错误而非空结果。2.2 布尔运算符不区分大小写运算符含义优先级NOT expr取反右结合最高expr AND expr逻辑与中expr OR expr逻辑或最低(expr)括号分组—解析器internal/query/parser.go采用经典的递归下降结构parseOr → parseAnd → parseNot → parsePrimary → parseComparison因此AND优先级高于ORNOT优先级最高且右结合。例如bd query statusopen OR statusblocked AND priority2等价于statusopen OR (statusblocked AND priority2)若想改变结合顺序必须显式使用括号如官方示例bd query (statusopen OR statusblocked) AND priority2词法层面AND/OR/NOT关键字大小写不敏感见 internal/query/lexer.goand、And均可识别。2.3 值类型与词法细节lexer 将比较右侧的值分为四类 tokenTokenIdent裸标识符、TokenString引号字符串、TokenNumber数字、TokenDuration如7d。几个值得注意的词法行为internal/query/lexer.go标识符字符集字母、数字、_、-、.、:、/均可出现在裸标识符中因此labelgt:merge-request、metadata.jira/sprint42这类带命名空间的值可以不加引号直接书写引号字符串支持与并提供\n、\t、\\、\、\转义未闭合字符串会报错数字前导标识符回退1-alpha、42day-sla这类数字开头但延续为标识符的值会被整体重新识别为标识符从而可以不加引号用于label1-alpha之类的比较孤立!报错单独出现!会得到提示did you mean ! or NOT?帮助用户纠正拼写。三、可查询字段总表以下字段完整继承自命令帮助文档并结合 internal/query/parser.go 的KnownFields表与 internal/query/evaluator.go 的求值分支给出约束3.1 核心字段字段取值支持运算符说明statusopen、in_progress、blocked、deferred、closed、!注意依赖阻塞dependency-blocked的 Issue 状态仍为open请用bd blocked命令查找对status的比较可用NOT statusx替代!priority整数0–4、!、、、、越界值报错priority0与priority4视为空匹配并给出提示typebug、feature、task、epic、chore、decision、!NOT typex等价于type!xassignee用户名或none谓词模式下!也可用none大小写不敏感null亦可表示未分配比较时忽略大小写owner用户名、!仅谓词模式owner 过滤无法下推为存储过滤器一律走内存谓词label标签名或none谓词模式下!也可用none表示无标签labelx AND labely要求同时命中多个标签title任意文本包含匹配contains非精确相等description任意文本或none包含匹配none表示描述为空notes任意文本包含匹配作用于 notes 字段parentIssue ID按父 Issue ID 精确匹配3.2 时间字段与别名字段含义可用别名created创建时间created_atupdated最后更新时间updated_atstarted首次进入in_progress的时间started_atclosed关闭时间closed_at时间字段支持完整比较运算符且比较按当天0:00 至次日 0:00区间解释会扩展到当天 23:59:59.999见 internal/query/evaluator.go。3.3 标识与布尔字段字段取值说明idIssue ID支持通配符bd-*以*结尾视为前缀匹配IDPrefix否则精确匹配specSpec ID支持通配符别名spec_id*结尾为前缀匹配否则也按前缀语义处理pinnedtrue/false亦接受yes/no/1/0置顶标记ephemeraltrue/false临时 Issue 标记templatetrue/false模板标记mol_typeswarm、patrol、work分子molecule类型3.4 元数据字段metadata从源码可见查询语言还支持两类元数据查询internal/query/parser.go 与 internal/query/evaluator.gometadata.keyvalue按顶层 JSON 元数据键值精确匹配键名保留原始大小写字段名本身转小写但metadata.之后的键后缀大小写敏感例如metadata.teamplatformhas_metadata_keykey判断是否存在某个元数据键对应 GH#1406。在谓词模式下元数据匹配通过反序列化 Issue 的 JSON 元数据并比较顶层标量实现见 internal/query/evaluator.go。四、日期与时间表达时间值支持三种写法internal/query/evaluator.go1. 相对时长duration——语义为距当前时刻 N 个单位之前后缀含义示例d天7d7 天前h小时24h24 小时前w周2w2 周前m月1my年1y大小写均可识别7D、24H同样有效。相对时长最终解析为now - duration的时间点再配合、等运算符使用updated7d表示7 天内更新过。2. 绝对日期2025-01-15 2025-01-15T10:00:00Z3. 自然语言日期由 internal/timeparsing 包解析tomorrow next monday in 3 days包含空格的短语需要用引号包裹。EvaluateAt(query, now)允许测试注入参考时间以验证相对时间语义见 internal/query/query_test.go 中对updated7d、created30d的断言。五、命令行参数与输出格式5.1 Flags 一览Flag简写默认值说明--all-afalse包含已关闭 Issue默认排除--limit-n50结果上限0表示不限量--long—false每个 Issue 输出多行详细信息--offset—0跳过前 N 个匹配结果0 起算仅在--proxied-server模式下支持--parse-only—false仅解析查询并打印 AST用于调试--reverse-rfalse反转排序方向--sort—空排序字段priority、created、updated、closed、status、id、title、type、assignee默认值50来自workapi.DefaultQueryLimit见 cmd/bd/query.go。所有 flag 在 cmd/bd/query.go 的init()中注册。5.2 行为细节表达式必填不带表达式直接运行会打印错误与帮助并以静默退出码返回cmd/bd/query.go默认排除已关闭 Issue但该隐藏是有条件的——只要表达式自身涉及status比较如statusclosed、NOT statusopen就按表达式意见执行只有表达式完全不关心状态时才应用默认排除。--all设置的正对应QueryRequest.IncludeClosedissueops/querier.go--parse-only不打开存储仅对表达式做词法/语法解析并输出Parsed query: ...形式的 AST 文本用于调试表达式合法性cmd/bd/query.go--offset限制--offset在非 proxied 模式下被拒绝负数--offset报must be non-negative且Offset与SortBy同时使用属于校验错误issueops/querier.go因为排序作用于查询界定的行集后再切页带偏移的分页会破坏排序语义。5.3 输出格式紧凑模式默认先打印Found N issues:随后每行一个 Issue格式与bd list一致——状态图标 ID [P优先级][类型]分配人 标签 标题cmd/bd/query.go--long模式每个 Issue 输出ID [P优先级] [类型] 状态、标题、分配人、标签等多行信息空结果打印No issues found matching query: 表达式JSON 输出与全局--json联动输出匹配结果数组outputJSON无匹配时输出空数组截断提示当结果多于当前页HasMore为真时在 stderr 打印提示配合--offset可以分页取完。六、执行原理过滤器下推与内存谓词双轨这是bd query最有价值的实现细节。求值器会把表达式翻译成两种形态之一internal/query/evaluator.go轨道一纯过滤器Filter-only。当表达式是单个比较、AND链、针对status/type的NOT、或纯标签的OR链时可以完整翻译为types.IssueFilter含Status、PriorityMin/Max、Labels、LabelsAny、TitleContains、CreatedAfter/Before等结构化字段下推到存储层由数据库执行并自行应用Limit。例如labelfrontend OR labelbackend会被优化为LabelsAny见 internal/query/evaluator.go 与 internal/query/query_test.go 的断言。轨道二谓词求值Predicate。当表达式含跨字段OR、复杂NOT、括号嵌套时如(statusopen OR statusblocked) AND priority2、NOT (statusclosed AND typebug)求值器先生成基础的预过滤条件extractBaseFilters再构造 Go 闭包谓词buildPredicate在内存中对候选行逐条求值internal/query/evaluator.go。关键的正确性保证见 issueops/querier.go 的方法契约谓词查询以无界方式读取全部候选行谓词看到完整匹配集再截取前Limit个匹配HasMore因此是精确计算而非猜测。历史上曾用max(3*Limit, 100)窗口截断谓词查询导致大工作区下 OR 查询返回任意前缀并漏报 has-more——该窗口已被移除代价是谓词查询会读取基础过滤条件放行的所有行宽泛表达式在大工作区上代价较高。测试层面对双轨行为有完整覆盖TestEvaluatorSimpleQueries验证纯过滤器翻译如statusopen AND priority1映射为StatusopenPriorityMin2TestEvaluatorComplexQueries验证RequiresPredicate标志internal/query/query_test.go端到端测试 cmd/bd/query_embedded_test.go 覆盖了相等、类型、分配人、优先级比较、AND/OR/NOT、--all、--limit、--sort、--reverse、--long、--parse-only及空结果等场景。七、官方示例逐条解析表达式含义statusopen AND priority1打开且优先级 ≥ 2P1–P0statusopen AND priority2 AND updated7d打开、优先级 ≤ 2P4–P2且 7 天内更新过(statusopen OR statusblocked) AND priority2打开或阻塞且优先级 ≤ 1typebug AND labelurgentbug 类型且带 urgent 标签NOT statusclosed排除已关闭等价于status!closedassigneenone AND typetask未分配的任务created30d AND status!closed创建超过 30 天且未关闭labelfrontend OR labelbackend带 frontend 或 backend 任一标签titleauthentication AND priority0标题包含 authentication 且优先级为 0最高组合实战建议# 紧急且 24 小时内更新过的打开 Issue bd query statusopen AND priority2 AND updated24h # 分页取回全部匹配配合 --proxied-server bd query typebug AND labelurgent --limit 50 --offset 50 # 调试复杂表达式 bd query --parse-only (statusopen OR statusblocked) AND priority2八、常见错误与排查症状原因与对策Error: query expression is required未提供表达式命令打印帮助后退出invalid status: xxx/priority must be between 0 and 4枚举值/数值越界核对字段取值表status only supports and ! operators字段不支持所选运算符参照字段表改用合法运算符unexpected character !孤立!应写作!或NOTexpected ) at position N括号不匹配检查分组unterminated string starting at position N引号未闭合--offset is only supported under --proxied-server当前模式不支持 offset 分页--offset must be non-negativeoffset 不能为负数invalid query expression: ...配合--parse-only查看 AST快速定位语法问题表达式校验遵循出错即报错绝不静默返回空页的原则空白、无法解析、字段不存在或运算符不合法的表达式一律返回ErrValidation并指明原因issueops/querier.go避免把拼写错误误读为仓库里没有匹配项。九、进阶与bd list、bd count的互补bd query的定位issueops/querier.go说明它独立于Reader.List存在而不是其变体ListRequest的每个字段都是 AND 关系无法表达typebug OR labelurgent更无法表达NOT (priority2 AND assigneenone)同时它不是裸 SQL 透传语言封闭在单行结构的字段集合内无表名、无 JOIN、无 ORDER BY 注入面。因此需要布尔组合、跨字段或/非关系时用bd query需要简单的字段过滤与排序分页时用bd list需要统计匹配数量时配合bd count。三者共享同一套过滤器词汇与排序字段语义学习成本可复用。若你正在为自动化流程CI 巡检、Agent 任务分发构造查询--json输出 --limit 0不限量 proxied 模式下的--offset分页可以组合成稳定的机器可读数据管道。参考文件索引命令实现与 flag 注册cmd/bd/query.go词法分析器internal/query/lexer.go语法解析器与字段白名单internal/query/parser.go求值器过滤器下推/谓词构建internal/query/evaluator.go单元测试internal/query/query_test.go端到端测试cmd/bd/query_embedded_test.go、cmd/bd/query_proxied_integration_test.go角色契约与执行语义issueops/querier.go【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价