帮助:Semantic MediaWiki
Semantic Mediawiki | |
---|---|
![]() | |
官方站点 | semantic-mediawiki.org |
Mediawiki官网页面 | Semantic Mediawiki |
Semantic Mediawiki又称“SMW”、“双马尾”,是MediaWiki的一个大型扩展插件集(expansion),它主要用来为基于Mediawiki搭建的站点提供数据存储和查询(data query)解决方案。
Semantic Mediawiki是一款开源插件,最早由德国人Markus Krötzsch和Denny Vrandecic创建。是全球范围内应用最为广泛的Mediawiki数据查询扩展。(类似的解决方案还有Cargo和Wiki Data)
SMW的定位
- SMW是一款功能性明确的MW“扩展”,实际上它比一般意义上的扩展(Expension)要庞大且复杂的多,安装、配置、使用都远比一般插件扩展复杂,更丰富的功能意味着更高的使用门槛和性能消耗。
- SMW的功能是为维基页面set data然后提供类数据库的query方式。如前文所述,SMW不是唯一的数据查询解决方案,它的两个主要类比概念是Cargo和Wikidata
SMW的应用
- 影视、文学、动漫等对图谱有着较高需求的站点,譬如章节目录、Episode分集信息的构建、存储、调用等等
- 一些数据结构呈二维扁平结构的游戏类数据。
替代方案
Lua查询MongoDB
对于数据本身呈多维树状结构的(比如JSON),推荐使用MongoDB进行存储查询,
- 详情参考:帮助:MongoDB支持
使用SMongo作为替代方案
在灰机,您可以选择使用SMongo作为SMW扩展{{#ask:}}
函数的替代品,同SMW相比他具有以下优势:
- 小巧灵活:只需要搬运一个模板和模块既可以使用,语法完全继承了SMW的ask函数,对于熟悉SMW的人来说,可以快速上手。
- 性能飙升:由于使用lua查询MongoDB,性能有着质的飞跃,响应速度是SMW的数十倍甚至百倍(视查询条件的复杂程度而定)。
- 限制较少:以query条件为例,由于性能问题,SMW限制了同时并列条件的最大数量(4个),在SMongo里,可以一口气写上40个条件也没问题。由于使用tabx存储、更新数据,也省去了#set之苦。
- 便于修改:核心是用Lua模块编写,有能力的开发者可以自行修改和扩展,带来更多的特性。
安全使用SMW
请勿滥用SMW,以免对数据库造成过大压力
- 关于请求限制:参加博客:让灰机变得更稳定_2,灰机对单次Ask的上限等核心参数进行了更高的约束,以避免滥用,但并不会影响正常使用。一次查询结果超过100的,可以分次查询,使用offset参数。
- 关于query的优化,一次show和一次ask对于服务器来说都是1次query,因此我们推荐多用ask,尽可能的少用show函数。ask取到多个参数然后使用format=template封装处理可以大大压缩请求压力。
灰机的SMW
目前灰机全面支持SMW,但是SMW并没有作为默认开启的组件,需要站长、管理员在站点管理面板手动开启SMW选项后才能生效。 一经开启后,SMW和以下组件会被启用:
- Semantic Mediawiki
- Semantic Forms
- Semantic Result Formats
- Arrays
- Data命名空间
- 详情请阅读:help:命名空间
已知的不兼容问题
由于灰机使用了MySQL5.6,导致部分SMW查询语法在灰机上会产生runtime exception的致命错误。该问题已经确认为SMW的bug(只兼容到MySQL5.5),包括可能不限于部分ask函数中的查询条件(例如条件组合和逻辑与的缩写方式等)。SMW官方确认会在下一个版本中予以修复(尚无时间表)
SMW特殊页面
- 特殊:询问(Special:Ask)
- 特殊:按属性搜索(Special:Search by property)
- 特殊:浏览(Special:Browse)
- 特殊:浏览/<页面名称>(Special:Browse/<页面名称>),查看指定页面的属性
- 特殊:概念(Special:Concepts)
- 特殊:属性(Special:Properties)
SMW基础概念
property与value
通过赋值,每个页面都可能拥有若干属性(property),以右图为例,亚巴顿的属性“Agility”的数值就是“17”
- 取值:通过#show函数,我们可以取到任意一个页面的任意一个值(只要存在)
{{#show:<页面名称>|?<属性名称>|link=}}
例如{{#show:亚巴顿|?agility|link=none}}
即可得到“17”
使用ASK函数查询(query)
- show函数只能展示一个数值,如果我们是想查询多个数值,就必须用到#ask函数
{{#ask:<条件>|?<属性名称1>|?<属性名称2>|?<属性名称3>……|其他参数}}
ask函数默认返回一个表格,例如{{#ask:[[category:防具物品]]|?name en|?Item cost}}
得到结果如左图。
需要注意的是,这里只是简单的介绍一下ask能做什么,对于SMW而言,#ask是最核心,最复杂的函数,这里不再展开赘述,如何灵活掌握和应用ask函数需要大量的实践和摸索。
如何查看页面上的已有数值(property)
通过特殊页面:“特殊:浏览(Special:Browse)”来实现
- 写法一:www.yoursite.huiji.wiki/wiki/特殊:浏览/页面名称
- 写法二:ww.yoursite.huiji.wiki/wiki/Special:Browse/页面名称
#set函数
我们在上面讲了如何取值,下面着重介绍如何赋值。解析器函数#set允许用户在页面中设定一个或若干数据(property及其value)
- 详情请阅读:帮助:解析器函数#set
#subobject函数与子对象
上述的#set函数是通过在页面上直接建立属性,这里“页面(PAGE)”就是对象。除此之外,SMW还允许每个页面上外挂若干个“子对象”,然后子对象也可以像页面一样拥有自己的属性和数值,结构见右图。
添加子对象
- 详情请阅读:帮助:解析器函数#subobject
查询子对象
在Lua中查询SMW
在lua中查询ask的效率要高很多很多,而且对结果的操作更加随心所欲,因为返回的结果是一个合法的luaTable,可以利用lua函数做各种处理。
mw.smw.ask
local _qry = {} local etty = { 'Activition', } for __ , _v in pairs(etty) do table.insert( _qry, '?'.._v ) end _qry.mainlabel = '-' _qry.limit = 1 table.insert(_qry, '[[Has skill id::'..xxxx..']]') local result = mw.smw.ask( _qry ) -------------------------------------- if result then result = result[1] ocal _qry = {} local etty = { 'Activition', } for __ , _v in pairs(etty) do table.insert( _qry, '?'.._v ) end _qry.mainlabel = '-' _qry.limit = 1 table.insert(_qry, '[[Has skill id::'..v['id']..']]') local result = mw.smw.ask( _qry ) -------------------------------------- if result then result = result[1] __activition = result['Activition'] or 'default value' end end
|