一、关于Velocity的基本配置
在Solr中,可以以多种方式返回搜索结果,如单纯的文本回复(XML、JSON、CSV等),也可以返回velocity,js等格式。而VelocityResponseWriter就是用于将返回velocity类型文本,以便直接用于结果呈现。
在Solr提供的example,其中的一个RequestHandler--/browse,使用了VelocityResponseWriter。其配置如下:
explicit velocity browse layout Solritas_test edismax text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 text 100% *:* 10 *,score text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename 3 on cat manu_exact content_type author_s ipod GB 1 cat,inStock after price 0 600 50 popularity 0 10 3 manufacturedate_dt NOW/YEAR-10YEARS NOW +1YEAR before after on content features title name html 0 title 0 name 3 200 content 750 on false 5 2 5 true true 5 3 spellcheck
关于velocity这个writer的定义如下:
处理一个流程的步骤如下:
从上述定义中开始分别查找显示层的内容(vm文件)与处理类的内容(wt的实现类。)explicit velocity browse layout Solritas_test
-
v.layout: Template name that wraps main template (v.template). Main template renders to a $content that can be used in layout template.
#** * Overall HTML page layout *# #parse("head.vm")#parse("header.vm")#parse("tabs.vm")$content
public class VelocityResponseWriterextends Objectimplements QueryResponseWriter
以下是关于VelocityResponseWriter的官方说明:http://wiki.apache.org/solr/VelocityResponseWriter
Introduction
VelocityResponseWriter (aka ) enables Solr to respond with content generated from templates. Along with technologies like SolrJS, this makes Solr itself capable of driving sophisticated search interfaces without the need for an intermediate application server between the browser and Solr.
See for more information.
Contents
Instructions to use, Solr 1.4+
These steps will get you up and running for the examples below:
- Download and install Solr 1.4.x
- Fire up Solr: cd example; java -Dsolr.solr.home=../contrib/velocity/src/main/solr/ -jar start.jar
- Index sample docs: cd example/exampledocs; java -jar post.jar *.xml
- Hit the examples below...
Sample Usage
- Renders browse.vm from conf/velocity. Faceted navigation included.
- Renders browse.vm, but overrides the header.vm from conf/velocity with the specified value.
- Renders browse.vm, adding in explanation views per hit, and a Velocity context dump at the end.
Using the VelocityResponseWriter in Solr Core
The VelocityResponseWriter is still a contrib component in Solr 1.4.x. In order to use it with the core distributions the following steps need to be followed:
The following jars need to be copied from contrib/velocity/src/main/solr/lib/ to $SOLR_HOME/lib:
- apache-solr-velocity-1.4-dev.jar
- velocity-1.6.1.jar
- velocity-tools-2.0-beta3.jar
- commons-beanutils-1.7.0.jar
- commons-collections-3.2.1.jar
The VelocityResponseWriter uses a more recent version of the commons lang jar than the current version of Solr core, so the jar commons-lang-2.4.jar from .../contrib/velocity/src/main/solr/lib/ should replace $SOLR_HOME/lib/commons-lang-2.1.jar
Add some configuration for this to solrconfig.xml like this:
Set up a in solrconfig.xml:
browse velocity.properties text/html;charset=UTF-8 Solritas velocity dismax *:* 10 *,score on title 1 text^0.5 title^1.5
Copy the .../contrib/velocity/src/main/solr/conf/velocity directory to $SOLR_HOME/conf/. This directory contains the Velocity templates that will be needed by the VelocityResponseWriter, and also a style sheet, main.css. The templates and style sheet can be edited to customize the display.
Instructions to use, Solr 4.0+
These steps will get you up and running for the examples below:
-
Check out Solr trunk: svn co
- Build Solr: ant clean example
- Fire up Solr: cd example; java -jar start.jar
- Index sample docs: cd example/exampledocs; java -jar post.jar *.xml
- Hit the examples below...
Sample Usage
- Renders browse.vm from conf/velocity. Faceted navigation included.
- Renders browse.vm, but overrides the header.vm from conf/velocity with the specified value.
- Renders browse.vm, adding in explanation views per hit, and a Velocity context dump at the end.
Options (All Versions)
-
v.template: template name to use, without the .vm suffix. If not specified, "default"[.vm] will be used.
-
v.template.<name>: overrides a file system template
-
debugQuery: if true, default view displays explanations for each hit and additional debugging information in the footer.
-
v.json: Escapes and wraps Velocity generated response with v.json parameter as a function.
-
v.layout: Template name that wraps main template (v.template). Main template renders to a $content that can be used in layout template.
-
v.base_dir: overwrites default template load path (conf/velocity/).
-
v.properties: specifies a Velocity properties file to be applied, found using the Solr resource loader mechanism. If not specified, no .properties file is loaded. Example: v.properties=velocity.properties where velocity.properties can be found using Solr's resource loader mechanism, for example in the conf/ directory (not conf/velocity which is for templates only). The .properties file could also be located inside a JAR in the lib/ directory, or other locations.
-
v.contentType: sets the value of the HTTP response's Content-Type header (in case (x)html pages should be UTF-8 (instead of ISO-8859-1) encoded, make sure you set this option to text/xml;charset=UTF-8 (for XHTML) and text/html;charset=UTF-8 (for HTML), respectively)
Velocity Context
-
esc: a Velocity instance
-
date: a Velocity instance
-
list: a Velocity instance
-
math: a Velocity instance
-
number: a Velocity instance
-
page: a instance. page only is added to the context when response is a .
-
request: a
-
response: a most of the time, but in some cases where doesn't like the request handlers output (, for example, causes a parsing "response") the response will be a object.
-
sort: a Velocity instance
TODO
- Ajax suggest
- Integrate/adapt to SolrJS
- Tie in SIMILE Timeline and SIMILE Exhibit
- Add links in default footer to this wiki page, the Solr request as XML format, and SOLR-620
- Fix multi-valued fields issue, and fl parameter usage.
- Work on "dist" target so this works easily with a nightly build.
- Make Velocity tools and engine configuration pluggable
二、Velocity文件定位过程
1、根据上述分析,首先定位layout.xml
#parse("head.vm")2、其中content的内容即为browse.vm#parse("header.vm")#parse("tabs.vm")$content
3、browse.vm中最主要的搜索结果为results_list.vm#parse("pagination_top.vm")## Show Error Message, if any#parse("error.vm")## Render Results, actual matching docs#parse("results_list.vm")#parse("pagination_bottom.vm")
#** * Render the main Results List *### Usually displayed inside#if($response.response.get('grouped')) #foreach($grouping in $response.response.get('grouped')) #parse("hit_grouped.vm") #end#else #foreach($doc in $response.results) #parse("hit.vm") ## Can get an extremely simple view of the doc ## which might be nicer for debugging ##parse("hit_plain.vm") #end#end
一般情况下使用hit.vm作呈现,它对页面作了一些美工。
在某些情况下,如debug的时候,就使用hit_plain.vm进行呈现,此时将所有的属性呈现出来。
二者的对比效果如下:
4、先查看hit_plain.vm#** * An extremely plain / debug version of hit.vm *#
#if( $foreach.count == 1 ) $fieldName: #end | ## Field Value(s)$esc.html($value) |
---|
就是将属性名与属性值呈现出来。
5、再看看hit.vm
#** * Called for each matching document but then * calls one of product_doc, join_doc or richtext_doc * depending on which fields the doc has *##set($docId = $doc.getFieldValue('id'))6、可以直接看richtest_doc.vm## Has a "name" field ? #if($doc.getFieldValue('name')) #parse("product_doc.vm") ## Has a "compName_s" field ? #elseif($doc.getFieldValue('compName_s')) #parse("join_doc.vm") ## Fallback to richtext_doc #else #parse("richtext_doc.vm") #end
#** * Render a complex document in the results list *### Load Mime-Type List and Mapping#parse('mime_type_lists.vm')## Sets:## * supportedMimeTypes, AKA supportedtypes## * mimeExtensionsMap, AKA extMap## Title#if($doc.getFieldValue('title')) #set($title = $esc.html($doc.getFirstValue('title')))#else #set($title = "["+$doc.getFieldValue('id')+"]")#end## URL#if($doc.getFieldValue('url')) #set($url = $doc.getFieldValue('url'))#elseif($doc.getFieldValue('resourcename')) #set($url = "file:///$doc.getFieldValue('resourcename')")#else #set($url = "$doc.getFieldValue('id')")#end## Sort out Mime-Type#set($ct = $list.get($doc.getFirstValue('content_type').split(";"),0))#set($filename = $doc.getFieldValue('resourcename'))#set($filetype = false)#set($filetype = $mimeExtensionsMap.get($ct))## TODO: falling back to file extension is convenient,## except when you don't have an icon for that extension## example "application/vnd.openxmlformats-officedocument.wordprocessingml.document"## document with a .docx extension.## It'd be nice to fall back to an "unknown" or the existing "file" type## We sort of do this below, but only if the filename has no extension## (anything after the last dot).#if(!$filetype) #set($filetype = $filename.substring($filename.lastIndexOf(".")).substring(1))#end## #if(!$filetype)## #set($filetype = "file")## #end## #if(!$supportedMimeTypes.contains($filetype))## #set($filetype = "file")## #end## Row 1: Icon and Title and mlt link由于本文件是example自带的呈现文件,其属性也按照自带的schemal.xml定义,并不适用于nutch的schema。## Icon ## Small file type icons from http://www.splitbrain.org/projects/file_icons (public domain) ## Title, hyperlinked $title ## Link for MLT / More Like This / Find Similar #if($params.getBool('mlt', false) == false) More Like This #end## Row 2?: ID / URL#Id: #field('id') ##自己修改 ##Time: #field('tstamp')## Resource Name#if($doc.getFieldValue('resourcename')) Resource name: $filename #elseif($url) URL: $url #end #if($ct) ($ct) #end## Author#if($doc.getFieldValue('author'))Author: #field('author')#end## Last_Modified Date#if($doc.getFieldValue('last_modified'))last-modified: #field('last_modified')#end## Main content of doc#field('content')## Display Similar Documents / MLT = More Like This#set($mlt = $mltResults.get($docId)) #set($mltOn = $params.getBool('mlt')) #if($mltOn == true)## div class=mlt#parse('debug.vm')Similar Items#end ## If has MLT enabled An Entries to show #if ($mltOn && $mlt && $mlt.size() > 0)#foreach($mltHit in $mlt) #set($mltId = $mltHit.getFieldValue('id'))
## Else MLT Enabled but no mlt results for this query #elseif($mltOn && $mlt.size() == 0)- #end ## end for each mltHit in $mlt
Title: $mltHit.getFieldValue('title')Author: $mltHit.getFieldValue('author') Description: $mltHit.getFieldValue('description')No Similar Items Found#end
因此,若要改变呈现的内容,可以直接修改此文件。如将
## Row 2?: ID / URL改为:#Id: #field('id')
## Row 2?: ID / URL则在页面不再显示id,而是显示时间。##自己修改 #Time: #field('tstamp')