ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Sanity 电商页面过时产品分析函数(Stale Products Analysis)实战指南

Sanity 电商页面过时产品分析函数(Stale Products Analysis)实战指南 Sanity 电商页面过时产品分析函数Stale Products Analysis实战指南【免费下载链接】sanitySanity Studio – Rapidly configure content workspaces powered by structured content项目地址: https://gitcode.com/GitHub_Trending/sa/sanity本指南围绕 Sanity Functions 示例stale-products-analysisREADME展开讲解如何构建一个随页面文档创建/更新自动触发、分析页面模块中商品年龄、并将分析结果写回页面的文档函数。你将掌握蓝图Blueprint中文档函数的完整配置、事件过滤器写法、GROQ 投影查询、本地测试全流程以及阈值与指标的自定义方法。一、问题与解决方案电商团队需要在页面上持续展示新鲜、与当前营销节奏匹配的商品。人工逐个追踪页面模块中商品的“年龄”从创建到现在的天数并识别过期商品既耗时又容易被忽略最终导致页面展示过时商品伤害用户体验与转化。该函数给出的自动化方案是每当 page 文档被创建或更新时自动计算页面模块中引用的每个商品在系统内的存在时长将超过 30 天的商品标记为isOld并把完整的年龄分析数据写回 page 文档的productAgeAnalysis字段供编辑人员直接监控与报表使用。从源码看index.ts核心链路为documentEventHandler接收 create/update 事件用createClient构造客户端useCdn: false、apiVersion: 2025-06-01用一条带条件投影的 GROQ 查询一次性拉取页面及其商品数据提取商品 → 按_id去重 → 计算createdAgeInDays/updatedAgeInDays→ 标记isOld按年龄倒序排序后通过client.patch(_id).set({productAgeAnalysis})写回页面。二、方案收益自动化新鲜度监控商品年龄由函数自动计算无需人工盘点过时内容识别超过 30 天的商品被自动标记为 stale数据驱动决策提供总商品数、过时商品数、平均年龄等统计页面优化用洞察指导编辑替换过期商品保持推荐内容新鲜可扩展监控对所有页面商品引用统一生效随内容规模自动扩展。三、兼容模板与前置 Schema该函数面向 Sanity E-commerce Shopify 模板设计特别适配“页面文档的modules中以 grid 布局引用商品”的结构。安装模板npm create sanitylatest -- --template shopify向 page 文档 schema 添加必需字段需要给page文档补充productAgeAnalysis字段readOnly: true由函数自动填充defineField({ name: modules, type: array, description: Editorial modules to associate with this collection, of: [ defineArrayMember({type: grid}), // Additional types can be added ], group: editorial, }), defineField({ name: productAgeAnalysis, title: Product Age Analysis, type: array, of: [ { type: object, fields: [ { name: product, title: Product, type: reference, to: [{type: product}], }, { name: ageInDays, title: Age in Days, type: number, }, { name: updatedAgeInDays, title: Days Since Last Update, type: number, }, { name: isOld, title: Is Stale Product, type: boolean, }, { name: createdAt, title: Created At, type: datetime, }, { name: lastUpdated, title: Last Updated, type: datetime, }, ], preview: { select: { title: product.title, productTitle: product.store.title, ageInDays: ageInDays, updatedAgeInDays: updatedAgeInDays, isOld: isOld, createdAt: createdAt, lastUpdated: lastUpdated, }, prepare({title, productTitle, ageInDays, updatedAgeInDays, isOld}) { const displayTitle productTitle || title || Untitled Product const createdAgeText ageInDays ? ${ageInDays}d old : Unknown age const updatedAgeText updatedAgeInDays ? ${updatedAgeInDays}d since update : Unknown const status isOld ? OLD : FRESH return { title: displayTitle, subtitle: ${status} - Created: ${createdAgeText} | Updated: ${updatedAgeText}, } }, }, }, ], description: Automatically populated by the stale-products-analysis function, readOnly: true, }),preview.prepare的输出正是上图中「Product Age Analysis」列表每行展示的内容红/绿状态标识 创建天数 更新天数product.store.title优先于product.title作为显示标题。四、实现步骤重要以下命令均需在项目根目录执行不要在studio/目录内。1. 初始化示例新项目npx sanity blueprints init --example stale-products-analysis已有项目npx sanity blueprints add function --example stale-products-analysis过程中会提示选择你的 organization 和 Sanity studio。2. 在蓝图中添加配置// sanity.blueprint.ts import {defineBlueprint, defineDocumentFunction} from sanity/blueprints export default defineBlueprint({ resources: [ defineDocumentFunction({ name: stale-products-analysis, memory: 1, timeout: 30, src: ./functions/stale-products-analysis, event: { on: [create, update], filter: _type page (delta::changedAny(modules) || (delta::operation() create defined(modules))), projection: {_id, _type, modules}, }, }), ], })要点解析on: [create, update]页面创建或更新时触发filter仅当文档类型为page且modules字段发生变更delta::changedAny(modules)或新建且已定义modulesdelta::operation() create defined(modules)时才执行可避免无关字段变更引发无谓运行projection事件负载只携带_id/_type/modules完整的商品详情由函数内 GROQ 查询拉取memory: 11GB、timeout: 30秒轻量函数配置两者也记录在 package.json 的blueprintResourceItem元数据中仓库根 sanity.blueprint.ts 会自动读取各functions/*/package.json的blueprintResourceItem并注册为蓝图资源。3. 安装依赖项目根目录npm install函数目录npm install sanity/functions cd functions/stale-products-analysis npm install cd ../..函数自身依赖sanity/client与sanity/functions版本见 package.jsonmain指向index.ts包类型为 ESM。4. 添加必需 schema 字段按上文「兼容模板」小节将productAgeAnalysis字段加入 page 文档 schema。5. 部署 schema在studio/目录内路径依模板结构调整cd studio npx sanity schema deploy cd ..五、本地测试文档函数要求测试用的文档 ID 真实存在于数据集中以下示例均基于真实文档 ID 操作。1. 基础函数测试先在studio/目录创建带商品引用的测试页面cd studio cat test-page.json EOF { _type: page, title: Test Page with Products, modules: [ { _type: grid, _key: test-grid, items: [ { _type: productReference, _key: test-product-ref, productWithVariant: { product: { _ref: existing-product-id, _type: reference } } } ] } ] } EOF npx sanity documents create test-page.json --replace cd .. npx sanity functions test stale-products-analysis --file studio/test-page.json --dataset production --with-user-token备选方案直接导出数据集里已有的真实页面cd studio npx sanity documents query *[_type page][0] ../real-page.json cd .. npx sanity functions test stale-products-analysis --file real-page.json --dataset production --with-user-token2. 交互式开发模式npx sanity functions dev会打开一个交互式 playground可用自定义数据调试函数。3. 自定义数据测试自定义数据同样必须使用数据集中真实存在的文档 IDcd studio REAL_DOC_ID$(npx sanity documents query *[_type page][0]._id | tr -d ) cd .. cat test-custom-page.json EOF { _type: page, _id: $REAL_DOC_ID, title: Custom Test Page, modules: [ { _type: grid, _key: custom-grid, items: [ { _type: productReference, _key: custom-product-ref, productWithVariant: { product: { _ref: existing-product-id, _type: reference } } } ] } ] } EOF npx sanity functions test stale-products-analysis --file test-custom-page.json --dataset production --with-user-token4. 真实文档数据测试最稳妥的方式是直接使用数据集中带商品模块的现有页面cd studio npx sanity documents query *[_type page defined(modules)][0] ../test-real-page.json cd .. npx sanity functions test stale-products-analysis --file test-real-page.json --dataset production --with-user-token仓库自带的示例输入文档见 document.json其中包含两个productReference条目product-123、product-456结构与上面的测试 JSON 完全一致。5. 开启调试日志函数内置了完整日志测试输出中可观察console.log( Page Product Age Analysis Function called at, new Date().toISOString()) console.log( Analyzing product ages for page:, _id) console.log( Found products:, uniqueProducts.map((p) p._id), ) console.log( Product age analysis:, {totalProducts, oldProducts, averageAge})测试要点使用真实文档 ID文档函数要求 ID 存在于数据集中用查询找测试文档npx sanity documents query是寻找合适测试文档的主要手段本地使用 Node.js v22.x与生产运行时保持一致用带商品引用的页面测试才能看到完整功能检查函数日志观察处理细节在 Sanity Studio 中验证分析结果没有合适页面就先造测试数据再跑函数。六、需求清单启用了 Functions 的 Sanity 项目Sanity E-commerce 模板及其 schema 类型page文档类型与modules字段已有product文档类型已有含productAgeAnalysis字段的更新版pageschema按上文新增页面文档的 modules 中须有 grid 布局下的商品引用本地开发使用 Node.js v22.x。七、运行流程与源码细节页面文档被创建或更新时函数自动触发收到 page 的 create/update 事件提取从 grid 模块中抽取商品引用分析基于创建与更新日期计算商品年龄统计计算年龄统计并标记过时商品回写将完整年龄分析数据更新到页面。样本输入文档{ _type: page, _id: page-123, title: Page with Product Grid, modules: [ { _type: grid, items: [ { _type: productReference, productWithVariant: { product: { _ref: product-123, _type: reference } } } ] } ] }结果分析所有被引用商品的年龄将超过 30 天的商品标记为 stale将分析数据存入页面productAgeAnalysis字段提供总商品数、过时商品数、平均年龄等统计。源码级关键实现index.tsGROQ 查询函数并未直接遍历事件投影里的 modules而是用一条条件展开查询拉取商品完整数据其中(_type grid) {...}与(_type productReference) {...}是 GROQ 的条件投影只有命中类型的字段才会被展开product-为引用穿越*[_id $id][0] { _id, modules[] { _type, (_type grid) { items[] { _type, (_type productReference) { productWithVariant { product- { _id, _createdAt, _updatedAt, title, store { title } } } } } } } }阈值常量STALE_PRODUCT_THRESHOLD_DAYS 30判断逻辑为isOld createdAgeInDays STALE_PRODUCT_THRESHOLD_DAYS基于创建日期注释说明创建日期优先、更重要年龄计算Math.floor((now - date) / (1000 * 60 * 60 * 24))分别计算createdAgeInDays与updatedAgeInDays去重用Mapstring, ProductWithDates按商品_id去重同一商品在多个模块中重复出现时只分析一次排序productAgeAnalysis.sort((a, b) b.ageInDays - a.ageInDays)最老的商品排最前空结果处理未找到商品时不会报错而是把productAgeAnalysis置为[]清空旧数据写回client.patch(_id, {set: {productAgeAnalysis}}).commit()一次 patch 写入所有分析条目扩展点extraProductData(page)函数集中了模块→商品的提取逻辑新增模块类型时只需在此追加对应分支源码注释也明确说明了这一点。八、自定义与扩展1. 修改过时阈值// 将阈值从 30 天改为 60 天 const isOld createdAgeInDays 60 // 或改用“距离上次更新”的判定 const isOld updatedAgeInDays 14 // 2 weeks since last update2. 增加分析指标const productAgeAnalysis uniqueProducts.map((product) { // ... existing logic return { // ... existing fields isVeryOld: createdAgeInDays 90, // Flag very old products category: getProductCategory(product), // Add category analysis lastModifiedBy: product.lastModifiedBy, // Track who last modified stalenessScore: calculateStalenessScore(createdAgeInDays, updatedAgeInDays), } })3. 处理不同模块类型page.modules?.forEach((module) { if (module._type grid module.items) { // ... existing grid logic } else if (module._type carousel module.products) { // Handle carousel modules with direct product references module.products.forEach((productRef) { if (productRef._ref) { // Add to products array } }) } })4. 自定义年龄计算策略// 为创建时间与更新时间设置不同权重 const weightedAge createdAgeInDays * 0.7 updatedAgeInDays * 0.3 // 不同商品类型使用不同阈值 const getAgeThreshold (product: ProductWithDates) { if (product.store?.productType seasonal) return 14 // 2 weeks for seasonal if (product.store?.productType evergreen) return 90 // 3 months for evergreen return 30 // Default 30 days }九、常见问题排查报错「Page not found」原因页面文档在数据集中不存在解决确认页面文档存在且_id正确。报错「No product references found in page modules」原因页面没有 grid 模块或模块中没有商品引用解决为页面模块添加商品引用或检查模块结构。函数执行了但没有分析数据出现原因模块引用的商品不存在或缺少日期字段解决确认被引用商品存在且_createdAt、_updatedAt字段有效。分析出的年龄不正确原因商品日期字段含无效或缺失数据解决检查商品文档的_createdAt、_updatedAt时间戳是否正确。函数执行超时原因页面商品引用过多或模块结构过于复杂解决调大蓝图配置中的timeout值或优化查询。十、相关示例Auto-Tag Function用 AI 自动为内容生成标签Slack Notify Function检测到过时商品时发送通知Product Mapping Function基于 Shopify 标签自动组织商品。【免费下载链接】sanitySanity Studio – Rapidly configure content workspaces powered by structured content项目地址: https://gitcode.com/GitHub_Trending/sa/sanity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表