MediaWiki单页多次设置Record属性如何让ask查询返回独立结果
SMW Record属性多实例独立查询实现方案
SMW默认将单个Wiki页面作为单一查询主体,同一页面内多次通过#set挂载的同个Record属性会被自动聚合,同名字段值会被合并为逗号分隔的字符串,要实现单组记录作为独立结果返回,有两种可落地方案,优先推荐第一种:
方案1:用子对象(Subobject)存储单组记录(稳定无兼容问题,推荐)
子对象是依附于父页面存在的独立SMW查询实体,每个子对象存储的属性值完全独立,不会和其他子对象、父页面本身的属性值合并,从根源上避免值聚合问题。
代码修改方式
将原来直接通过#set赋值的写法,调整为每组Record单独存入一个#subobject块:
原赋值代码:
{{#set: Has Some Record=record1_field1; record1_field2}} {{#set: Has Some Record=record2_field1; record2_field2}}修改后代码:
{{#subobject:record_group_1 |Has Some Record=record1_field1; record1_field2 }} {{#subobject:record_group_2 |Has Some Record=record2_field1; record2_field2}}说明:
#subobject:后跟随的record_group_1/record_group_2是自定义的子对象唯一标识,可省略,省略后SMW会自动生成随机ID,不影响查询效果,仅方便后续手动定位编辑对应记录。
查询写法
无需特殊参数,正常编写#ask查询即可,SMW会自动将每个存储了目标Record属性的子对象作为独立结果行返回:
{{#ask: [[Has Some Record::+]] |?Has Some Record.field1 |?Has Some Record.field2 |mainlabel=- |headers=plain }}
执行查询后会直接输出两组独立结果,和预期效果完全一致。
方案2:查询层模板拆分聚合值(适合存量数据场景,有兼容风险)
如果已有大量存量页面使用多次#set的写法、批量改造成本过高,可以不修改原有赋值逻辑,在查询输出层做值拆分:
- 给
#ask查询指定template输出格式,将聚合后的字段值传递给自定义模板 - 在模板中借助ParserFunctions扩展的
#explode、#arraymap等解析函数,将逗号分隔的聚合值拆分为数组,按索引逐组匹配输出
示例查询代码:
{{#ask: [[Has Some Record::+]] |?Has Some Record.field1=field1_all |?Has Some Record.field2=field2_all |format=template |template=SplitRecordRow |sep= }}
后续在Template:SplitRecordRow页面编写拆分循环逻辑即可。
注意:该方案存在明显缺陷:如果Record字段值本身包含英文逗号,会出现拆分错位;如果同页面下不同Record实例的字段值数量不匹配,也会出现值乱序问题,仅适合字段值格式高度固定、无特殊字符的场景。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

