You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过API修改$byCategory投影?如何自动设置EventStore中该投影为last?

修改EventStore的$byCategory系统投影及自动设置为last的方法

一、通过API修改$byCategory投影

$byCategory是EventStore的内置系统投影,默认用来按分类(优先取事件元数据的$category,无则用事件类型前缀)把事件链接到对应分类流。要修改它,得通过EventStore的投影API操作,步骤如下:

  1. 确认权限:确保你有EventStore的管理员权限(默认用户名admin,密码changeit),系统投影的修改需要高权限才能执行。
  2. 获取当前投影定义:发送GET请求拿到投影的查询逻辑:
    curl -X GET http://localhost:2113/projection/$by_category -u admin:changeit
    
    响应的JSON里,query字段就是投影的JavaScript代码,这是我们要修改的核心部分。
  3. 调整为last模式的逻辑:如果希望每个分类流只保留最新的事件,需要在linkTo方法里加overwrite: true参数(覆盖该分类流的旧事件),示例修改后的query:
    fromAll()
      .when({
        $any: function(state, event) {
          // 提取分类:先看元数据的$category,没有就用事件类型的前缀(比如UserCreated -> User)
          var category = event.metadata["$category"] || event.type.split('-')[0];
          // 链接事件到分类流,overwrite: true会替换该流的最后一个事件
          linkTo(category, event, { overwrite: true });
        }
      })
    
  4. 提交修改后的投影:发送PUT请求把新的query提交给API:
    curl -X PUT http://localhost:2113/projection/$by_category/query \
      -u admin:changeit \
      -H "Content-Type: application/json" \
      -d '{
        "query": "fromAll().when({$any: function(state, event) { var category = event.metadata[\"$category\"] || event.type.split(\"-\")[0]; linkTo(category, event, { overwrite: true }); }})"
      }'
    
    执行后投影会重新处理事件,之后每个分类流就只会保留最新的那条事件了。

二、自动设置为last的实现方式

EventStore没有直接的启动参数能预设系统投影的逻辑,但可以通过两种方式自动完成配置:

1. 启动后自动执行API脚本

可以写一个启动脚本,等EventStore完全启动后,自动调用上述API修改投影。比如在shell脚本里:

# 等待EventStore启动完成(时间根据实际情况调整)
sleep 10

# 更新$byCategory投影为last模式
curl -X PUT http://localhost:2113/projection/$by_category/query \
  -u admin:changeit \
  -H "Content-Type: application/json" \
  -d '{
    "query": "fromAll().when({$any: function(state, event) { var category = event.metadata[\"$category\"] || event.type.split(\"-\")[0]; linkTo(category, event, { overwrite: true }); }})"
  }'

把这个脚本和EventStore的启动命令绑定(比如docker-compose的command里,或者systemd服务的ExecStartPost),就能实现启动后自动配置。

2. 创建自定义持久化投影(更推荐)

因为系统投影在EventStore升级时可能被重置,更稳妥的做法是创建一个自定义投影替代$byCategory,设置为持久化并自动启动:

  • 发送POST请求创建新投影:
    curl -X POST http://localhost:2113/projections/transient \
      -u admin:changeit \
      -H "Content-Type: application/json" \
      -d '{
        "name": "$by_category_last",
        "query": "fromAll().when({$any: function(state, event) { var category = event.metadata[\"$category\"] || event.type.split(\"-\")[0]; linkTo(category, event, { overwrite: true }); }})",
        "enabled": true,
        "emitEnabled": true,
        "persistState": true
      }'
    
    这个自定义投影会永久保留你的配置,不会被系统升级影响,而且启动后会自动运行。

注意事项

  • 修改系统投影前,建议先备份数据,避免意外丢失事件链接。
  • 如果你的EventStore开了安全认证,要确保API请求携带正确的认证信息。
  • overwrite: true是针对链接事件到流的操作,会替换目标流的最后一个事件;如果需要的是其他"last"逻辑(比如只追踪每个分类的最后事件状态),可以调整投影里的state处理逻辑。

内容的提问来源于stack exchange,提问作者Andriy Drozdyuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:47:21