如何为Sesam的read-entities管道实体添加命名空间?
在Sesam管道中为实体添加命名空间的解决方案
嗨,我来帮你搞定这个给Sesam管道里的实体添加命名空间的问题!先理一理现状:你的read-entities管道从REST API拉回的实体里,只有源数据集的_id带命名空间,其他子实体都没有。下面给你几个实用的解决办法:
方法1:在最后一步DTL里手动给返回的实体加命名空间
这是最直接的方案,不需要改动API,就在管道的最后一个DTL转换里处理HTTP返回的实体。你可以遍历响应里的每个实体,给它们加上带命名空间的_id,或者给字段添加上命名空间前缀。
修改后的管道配置大概是这样:
{ "_id": "read-entities", "type": "pipe", "source": { "type": "dataset", "dataset": "global-entities" }, "transform": [ { "type": "dtl", "rules": { "default": [ ["copy", "*"], ["add", "::foo", ["first", "_S.entity:foo"] ] ] } }, { "type": "http", "system": "entities", "url": "/transform" }, { "type": "dtl", "rules": { "default": [ ["add", "entities", ["map", "_S.response", ["lambda", // 从源数据的_id里提取命名空间,加上随机值生成带命名空间的唯一_id ["add", "_id", ["concat", ["split", "_S._root._id", ":"][0], ":", ["random"]]], // 给字段加上命名空间前缀,比如把foo改成entities:foo ["add", "entities:foo", "_S.foo"] ] ] ] ] } } ] }
这里的逻辑是:
- 用
map遍历HTTP返回的每个子实体 - 从源数据的
_id(比如namespace:fuubar)里拆分出命名空间部分 - 给每个子实体生成带命名空间的
_id(这里用了random保证唯一性,你也可以换成实体本身的唯一标识字段) - 同时把原来的字段(比如
foo)改成带命名空间前缀的格式
方法2:让API直接返回带命名空间的实体(如果API支持的话)
如果你的/transform API可以接收命名空间参数,那更优雅的做法是把源数据的命名空间传递给API,让它直接返回带命名空间的实体。
你可以在第一个DTL里先提取命名空间,然后在HTTP请求里传过去:
{ "_id": "read-entities", "type": "pipe", "source": { "type": "dataset", "dataset": "global-entities" }, "transform": [ { "type": "dtl", "rules": { "default": [ ["copy", "*"], ["add", "::foo", ["first", "_S.entity:foo"] ], // 从源数据的_id里提取命名空间部分 ["add", "namespace", ["split", "_S._id", ":"][0]] ] } }, { "type": "http", "system": "entities", // 把命名空间作为URL参数传递给API "url": "/transform?namespace={namespace}", // 或者作为请求体的一部分发送 "method": "POST", "body": ["merge", "_S", {"namespace": "_S.namespace"}] }, { "type": "dtl", "rules": { "default": [ ["add", "entities", "_S.response"] ] } } ] }
这种方法需要API端配合处理这个参数,返回已经带命名空间的实体,这样管道里就不用额外做转换了。
方法3:全局配置默认命名空间(适合统一场景)
如果你的Sesam系统里所有实体都需要统一的命名空间,也可以看看Sesam的全局配置,能不能给数据源或者系统设置默认命名空间。这样所有生成的实体都会自动带上命名空间,不用每个管道单独处理。
你可以根据自己的实际情况选最合适的方法,比如API不能改的话就用方法1,API能配合的话方法2更省心。
内容的提问来源于stack exchange,提问作者4hlberg
相关产品推荐
相关产品推荐

