Template:Type (zh-hans) Record型(记录型)数据类型适用于那些采用由其他类型的取值所组成的属性取值,且根据其属性页面上的Has fields(具有字段……)声明,记录的具体字段的次序和类型均固定不变。记录取值当中的具体字段采用英文分号(;)分隔。
在Semantic MediaWiki的早期版本当中,记录型属性又称为多值型属性(many-valued properties)或多元属性(n-ary properties)。
声明与使用[edit]
记录型属性的声明方法是,在其相应的属性页面上写上[[has type::record]],并采用属性Has fields来设定记录字段的类型。 例如,要定义具有一个日期型字段、一个页面型字段以及一个数值型字段的记录,可以这样写:
[[has fields::Date; Page; Number]]
采取类似的方式,可为该记录设置任何的类型列表。建议记录当中的字段数量不要超过5个,但更大型的记录也是可以的。 记录大小存在着一些技术限制,因此拥有超过50个字段的记录声明很可能会失败。 请注意,相对于这个字段数量限制,字段少得多的记录对于人类编者来说早已无法使用。
当在页面上使用记录型属性时,具体字段的取值是通过一个分号分隔型取值来提供的。 如果如上声明为属性myrecord,则可在某个页面上写出下列标注:
[[myrecord::May 12 1005; Some pagename; 1234]]
在为记录型属性设置取值时,亦可通过保持相应字段为空或者将其设置为问号,从而留下其中一些字段不予设置:
[[myrecord::May 12 1005; ?; 1234]] [[myrecord::May 12 1005;; 1234]]
亦可完全略去位于记录末端的取值:
[[myrecord::May 12 1005; Some pagename]]
如果为记录当中某个字段所声明的数据类型并不允许已经赋予该字段的取值, Semantic MediaWiki则会尝试保留该字段为空,并将该取值用作下一字段的取值。 例如,[[myrecord::Some pagename; 1234]]将被解释为[[myrecord::?; Some pagename; 1234]]。
示例[edit]
现在,让我们举个关于使用记录的典型例子:假设您希望在关于美国的一个维基页面当中,存储关于历届美国总统的信息。其中,只需写出[[has president::John F. Kennedy]],即可声明肯尼迪(Kennedy)在历届总统之列。但是,这样并不能让您看到肯尼迪究竟何时当得总统,而且也不可能找出现任总统。
肯尼迪是第35届美国总统,从1961年开始就职,直至1963年遇刺;这样的事实是由各种各样本属一体的信息所构成的。如果该页面上包含许多总统的话, 设定独立的属性取值[[has president::John F. Kennedy]]、[[in office since::1961]]、[[in office until::1963]],并不会解决问题,因为这样我们就搞不清到底哪些任职日期(in-office dates)属于哪位总统。
一种可能的解决办法就是,将属性has president声明为一个具有字段[[has fields::Page; Date; Date]]的记录。 这样,即可将上述事实写作[[has president::John F. Kennedy; 1961; 1963]],以便把这些信息编组在一起。 如上所述,如果某些字段未知或不适用的话,亦可略去它们,比如,在还不知道离职日期的情况下,可以这样写:[[has president::Barack Obama; 2009]]。
这个建模问题另一个可能的解决办法就是,为每个总统任期(presidency)分别建立一篇文章,并且为此文赋予具体的字段取值。 例如,可能备有的一个称为肯尼迪的总统任期的页面,并且采用关于人员、就职日期和离职日期的具体属性取值对此页面加以标注。 这样,就可以利用行内查询,向关于美国的页面当中插入关于历届总统的信息。
语义搜索[edit]
可以采用类似于所有其他属性的方式,将记录型属性用于搜索页面;详情请参见语义搜索。 与任何属性一样,可以利用通配符+来选择某个记录型属性为某一取值的所有页面,如{{#ask: [[Employment::+]] }}。 要找出记录中的某个字段为特定取值的那些页面,只需列出要匹配的那些取值并采用分号加以分隔即可。 如果不在乎这些数据类型之一的取值,则可采用问号?来匹配包括省略在内的任何取值。
在记录查询当中,为字段所指定的那些取值,可依据相应字段的数据类型来书写。 对于大多数的数据类型,这就意味着,可以配合每个字段采用代表非的!、代表小于等于的<之类的比较操作符。
例如,查询
{{#ask: [[Employment:: ?; !professorship; <July 1950; ?]] }}
将依据雇主字符串employer的任意取值来选择属性Employment的取值,而且,其中,职位字符串title不是"professorship"(教授职位),起始日期为1951年7月之前,且结束日期为任意取值。
当在查询结果里面显示记录取值的时候,可采用打印输出参数index来获得记录的特定字段。 例如,可以写出如下查询:
{{#ask: [[U.S.A.]] | ?has president | ?has president#name |+index=1 | ?has president#start |+index=2 | ?has president#end |+index=3 }}
从而,用于在一张表格之中显示所有的美国总统: 第一列显示的是完整记录,第二列显示的仅仅是第一个字段(name),而第三列和第四列则分别显示的是第三个和第四个字段(start of office和end of office)。
请注意:该查询的唯一"结果"就是页面U.S.A,因而该表格只有一行,显示的是该页面has president字段的全部取值,而不是分别针对每位总统的多个行。对于后一种情况,采用记录是无法实现的。
另请注意的是,这可能会导致某些并不直观的查询结果。 尽管如下查询运用了若干的SMW查询条件来选择匹配的维基页面:
{{#ask: [[Employment:: ?; !professorship; <July 1950; ?]] }}
但其最终结果仍将包含这些匹配的维基页面全部的就业情况(employments) - 甚至还包括那些并不符合查询条件的结果 - 而这是因为SMW处理记录的方式所造成的 (换句话说就是,首先查询条件用于匹配页面,在后续步骤当中,则返回的是所考虑的相应属性的全部取值 - 而不论其是否符合查询条件)。
限制[edit]
对于SMW 1.6版及其以上版本,至少下列限制当中的一些已不再存在。
- 无法采用专用的Allows value(允许取值)属性来限制记录任意字段的那些取值。
- 无法采用专用的Display units(显示用计量单位)属性来控制特定字段的呈现方式。
- 无法设定属性取值的布局;这些取值将始终显示为逗号分隔型列表。
- 记录字段无法成为Timelines(时间轴)或Maps(地图)之类专用查询格式的基础。
- 记录无法嵌套,因而只能由简单的数据类型构成。
备选手段[edit]
作为数据类型记录的替代手段,亦可考虑采用Semantic Internal Objects(语义内部对象)扩展。
- 到底何时采用数据类型记录,而何时又采用Semantic Internal Objects(语义内部对象,SIO)呢?
如果存在一对一型(页面对属性取值)关系(利用表单和模板来强制实现),则可采用二者当中的任意一个,但记录会比较容易些。
如果是一对多型关系,则SIOs会比较合适, 因为这样您就可以针对一个属性对它们加以查询,而又获取到其余的属性(参见如下示例)。 可将它们想象成为不必具有各自页面的页面(会把您的维基站点搞得乱七八糟)。
示例页面"Semantic City"(语义页面)
该市有几座博物馆:
- {{museum|Museum of Modern Art|1000|1800}}
- {{museum|Museum of Natural History|0930|1730}}
其中,您的博物馆模板将设置一个内部对象
{{#set_internal:is museum in city |has name={{{1}}} |has opening time={{{2|}}} |has closing time={{{3|}}} }}
并且,也会显示某些东西。
现在,即可查询指定城市的博物馆,并显示其开馆时间。
{{#ask: [[is museum in city::Semantic City]] [[has name::~*History*]] |?has name=Museum |?has opening time=opens |?has closing time=closes |mainlabel=- }}