enonic-guillotine-query-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Enonic Guillotine Query Builder

Enonic Guillotine 查询构建器

Procedures

操作流程

Step 1: Scan the workspace for existing Guillotine usage
  1. Execute
    node scripts/find-guillotine-targets.mjs .
    to inventory files containing Guillotine markers (query strings, library imports, endpoint references).
  2. If a Node runtime is unavailable, search the workspace manually for
    guillotine
    ,
    queryDsl
    ,
    queryDslConnection
    , or
    /lib/guillotine
    in
    .ts
    ,
    .js
    ,
    .graphql
    , and
    .gql
    files.
  3. Note the Guillotine version in use: if
    query(query: "...")
    string-based fields are found, the project uses the deprecated 5.x-style API; if
    queryDsl
    /
    queryDslConnection
    are found, the project uses 6.x+ DSL.
  4. If both styles coexist, flag the deprecated usage for migration.
Step 2: Load the Guillotine API reference
  1. Read
    references/guillotine-reference.md
    before composing any query.
  2. Read
    references/compatibility.md
    when the workspace targets or migrates between Guillotine versions.
Step 3: Determine the query shape
  1. Identify the operation the user needs:
    • Single content fetch: Use
      get(key)
      .
    • Direct children: Use
      getChildren(key)
      or
      getChildrenConnection(key)
      for pagination.
    • Filtered search: Use
      queryDsl(query)
      for a flat list or
      queryDslConnection(query)
      for pagination, aggregations, or highlighting.
    • Content type metadata: Use
      getType(name)
      or
      getTypes
      .
  2. If pagination is needed, prefer connection variants (
    queryDslConnection
    ,
    getChildrenConnection
    ) and guide the caller to pass
    after
    /
    first
    .
  3. If aggregations or highlighting are needed, require
    queryDslConnection
    — these features are not available on
    queryDsl
    .
Step 4: Construct the content type fragment
  1. Derive the GraphQL type name from the content type descriptor by replacing dots (
    .
    ) and colons (
    :
    ) with underscores (
    _
    ), and removing hyphens (
    -
    ) while capitalizing the following letter. The first letter of each segment after a colon is capitalized. Example:
    com.enonic.app.myapp:BlogPost
    com_enonic_app_myapp_BlogPost
    . For built-in types:
    portal:template-folder
    portal_TemplateFolder
    .
  2. Use an inline fragment to access the type-specific
    data
    field:
    ... on <GraphQLTypeName> { data { ... } }
    .
  3. For content references (ContentSelector, ImageSelector, MediaSelector), follow the reference with a nested inline fragment on the target type.
  4. For RichText / HtmlArea fields, include
    processedHtml
    and optionally
    links
    ,
    images
    ,
    macros
    sub-fields. Use the
    processHtml
    input argument for absolute URLs or srcset widths.
Step 5: Build query filters and sorting
  1. Use Query DSL input types. Each
    QueryDSLInput
    must contain exactly one expression field.
  2. Combine multiple conditions using
    boolean
    with
    must
    ,
    should
    ,
    mustNot
    , and
    filter
    arrays.
  3. For date or numeric ranges, use the
    range
    expression with
    gt
    /
    gte
    /
    lt
    /
    lte
    and the correct
    DSLExpressionValueInput
    type (
    localDate
    ,
    localDateTime
    ,
    instant
    ,
    long
    ,
    double
    ).
  4. For sorting, use
    SortDslInput
    with
    field
    and
    direction
    (
    ASC
    /
    DESC
    ).
  5. Read
    references/examples.md
    when the query pattern matches a documented example.
Step 6: Add aggregations and highlighting (if needed)
  1. Pass
    aggregations
    as an array of
    AggregationInput
    objects on
    queryDslConnection
    .
  2. Each aggregation requires a unique
    name
    and exactly one aggregation type field (
    terms
    ,
    dateRange
    ,
    stats
    , etc.).
  3. For highlighting, pass
    highlight
    with a
    properties
    array specifying
    propertyName
    for each field to highlight.
  4. Read aggregation and highlight results from
    aggregationsAsJson
    and
    highlightAsJson
    on the connection result.
Step 7: Generate TypeScript types (if requested)
  1. Read
    assets/guillotine-query.template.ts
    as the starting template.
  2. Replace
    __APP_KEY__
    ,
    __CONTENT_TYPE__
    ,
    __GRAPHQL_TYPE__
    , and
    __FIELDS__
    placeholders with the actual content type values.
  3. Add typed fields to the
    Data
    interface matching the content type schema fields requested in the query.
  4. For connection queries, use the
    ContentConnection<T>
    generic with the specific content type.
Step 8: Set site context (if applicable)
  1. If the query targets a specific site, set
    siteKey
    on the
    guillotine
    field or instruct the caller to set the
    X-Guillotine-SiteKey
    HTTP header.
  2. Use
    ${site}
    placeholder in path arguments for site-relative queries.
  3. Use
    _path(type: siteRelative)
    to return site-relative paths.
Step 9: Validate the query
  1. Verify all inline fragment type names use underscores, not the original descriptor format.
  2. Confirm
    queryDsl
    /
    queryDslConnection
    are used instead of the deprecated
    query
    /
    queryConnection
    .
  3. Ensure
    QueryDSLInput
    objects contain exactly one expression field.
  4. Verify
    DSLExpressionValueInput
    objects contain exactly one value type field.
  5. Check that aggregation and highlight are only used on connection variants.
  6. Read
    references/troubleshooting.md
    if the query returns unexpected nulls, empty results, or type errors.
步骤1:扫描工作区中现有的Guillotine使用情况
  1. 执行
    node scripts/find-guillotine-targets.mjs .
    来盘点包含Guillotine标记(查询字符串、库导入、端点引用)的文件。
  2. 如果没有Node运行时,手动在工作区的
    .ts
    .js
    .graphql
    .gql
    文件中搜索
    guillotine
    queryDsl
    queryDslConnection
    /lib/guillotine
  3. 记录使用的Guillotine版本:如果发现了基于
    query(query: "...")
    字符串的字段,说明项目使用的是已弃用的5.x风格API;如果发现
    queryDsl
    /
    queryDslConnection
    ,则项目使用6.x+的DSL。
  4. 如果两种风格共存,标记弃用用法以便迁移。
步骤2:加载Guillotine API参考
  1. 编写任何查询之前先阅读
    references/guillotine-reference.md
  2. 当工作区要适配Guillotine版本或在不同版本间迁移时,阅读
    references/compatibility.md
步骤3:确定查询结构
  1. 识别用户需要的操作:
    • 单内容获取:使用
      get(key)
    • 直接子内容:使用
      getChildren(key)
      ,需要分页时使用
      getChildrenConnection(key)
    • 带过滤的搜索:获取平级列表使用
      queryDsl(query)
      ,需要分页、聚合或高亮时使用
      queryDslConnection(query)
    • 内容类型元数据:使用
      getType(name)
      getTypes
  2. 如果需要分页,优先使用连接变体(
    queryDslConnection
    getChildrenConnection
    ),引导调用方传入
    after
    /
    first
    参数。
  3. 如果需要聚合或高亮功能,必须使用
    queryDslConnection
    ——
    queryDsl
    不支持这些特性。
步骤4:构建内容类型片段
  1. 从内容类型描述符推导GraphQL类型名:将点(
    .
    )和冒号(
    :
    )替换为下划线(
    _
    ),删除连字符(
    -
    并将后续字母大写,冒号后每个分段的首字母大写。示例:
    com.enonic.app.myapp:BlogPost
    com_enonic_app_myapp_BlogPost
    。内置类型示例:
    portal:template-folder
    portal_TemplateFolder
  2. 使用内联片段访问类型专属的
    data
    字段:
    ... on <GraphQLTypeName> { data { ... } }
  3. 对于内容引用(ContentSelector、ImageSelector、MediaSelector),在引用后添加针对目标类型的嵌套内联片段。
  4. 对于RichText / HtmlArea字段,包含
    processedHtml
    ,可选包含
    links
    images
    macros
    子字段。需要绝对URL或srcset宽度时使用
    processHtml
    输入参数。
步骤5:构建查询过滤和排序规则
  1. 使用Query DSL输入类型,每个
    QueryDSLInput
    必须仅包含一个表达式字段。
  2. 使用
    boolean
    搭配
    must
    should
    mustNot
    filter
    数组组合多个条件。
  3. 对于日期或数值范围,使用
    range
    表达式搭配
    gt
    /
    gte
    /
    lt
    /
    lte
    和正确的
    DSLExpressionValueInput
    类型(
    localDate
    localDateTime
    instant
    long
    double
    )。
  4. 排序时使用
    SortDslInput
    搭配
    field
    direction
    ASC
    /
    DESC
    )。
  5. 如果查询模式与文档中的示例匹配,可参考
    references/examples.md
步骤6:添加聚合和高亮(如有需要)
  1. queryDslConnection
    上将
    aggregations
    作为
    AggregationInput
    对象数组传入。
  2. 每个聚合需要唯一的
    name
    和仅一个聚合类型字段(
    terms
    dateRange
    stats
    等)。
  3. 高亮功能需传入
    highlight
    ,其
    properties
    数组指定每个要高亮的字段的
    propertyName
  4. 从连接结果的
    aggregationsAsJson
    highlightAsJson
    中读取聚合和高亮结果。
步骤7:生成TypeScript类型(如有需求)
  1. 读取
    assets/guillotine-query.template.ts
    作为初始模板。
  2. __APP_KEY__
    __CONTENT_TYPE__
    __GRAPHQL_TYPE__
    __FIELDS__
    占位符替换为实际的内容类型值。
  3. Data
    接口中添加与查询中请求的内容类型schema字段匹配的带类型字段。
  4. 对于连接查询,使用搭配具体内容类型的
    ContentConnection<T>
    泛型。
步骤8:设置站点上下文(如适用)
  1. 如果查询针对特定站点,在
    guillotine
    字段上设置
    siteKey
    ,或指导调用方设置
    X-Guillotine-SiteKey
    HTTP头。
  2. 在路径参数中使用
    ${site}
    占位符实现站点相对查询。
  3. 使用
    _path(type: siteRelative)
    返回站点相对路径。
步骤9:验证查询
  1. 确认所有内联片段类型名使用下划线,而非原始描述符格式。
  2. 确认使用的是
    queryDsl
    /
    queryDslConnection
    而非已弃用的
    query
    /
    queryConnection
  3. 确保
    QueryDSLInput
    对象仅包含一个表达式字段。
  4. 确认
    DSLExpressionValueInput
    对象仅包含一个值类型字段。
  5. 检查聚合和高亮仅在连接变体上使用。
  6. 如果查询返回意外的null、空结果或类型错误,参考
    references/troubleshooting.md

Error Handling

错误处理

  • If
    get
    returns null, verify the key is a valid content path or ID and that the correct branch (draft vs master) is targeted.
  • If inline fragment fields are null, confirm the GraphQL type name uses underscores and matches the content type descriptor exactly.
  • If
    queryDsl
    returns empty results, simplify to
    matchAll: {}
    to confirm data exists, then re-add filters one at a time.
  • If aggregation or highlight results are null, verify the query uses
    queryDslConnection
    , not
    queryDsl
    .
  • If the deprecated
    query
    field is used, read
    references/compatibility.md
    to migrate to
    queryDsl
    with DSL syntax.
  • If
    scripts/find-guillotine-targets.mjs
    cannot run, scan the workspace manually for Guillotine markers and continue.
  • 如果
    get
    返回null,验证key是有效的内容路径或ID,且目标分支正确(草稿版 vs 正式版)。
  • 如果内联片段字段为null,确认GraphQL类型名使用下划线,且与内容类型描述符完全匹配。
  • 如果
    queryDsl
    返回空结果,简化为
    matchAll: {}
    确认数据存在,再逐个重新添加过滤条件。
  • 如果聚合或高亮结果为null,确认查询使用的是
    queryDslConnection
    而非
    queryDsl
  • 如果使用了已弃用的
    query
    字段,参考
    references/compatibility.md
    迁移到使用DSL语法的
    queryDsl
  • 如果
    scripts/find-guillotine-targets.mjs
    无法运行,手动扫描工作区的Guillotine标记后继续操作。