`
mozhenghua
  • 浏览: 323242 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Solr Schema XML DTD校验

阅读更多

 

     由于编辑solr的schema文件的过程中,时常会发生一些小错误,类似于,“true” 写成了“ture”

或者“multiValued”写成“multivalue”,虽然是手误但是往往会造成很诡异的错误,并且非常难排查错误。类似这样的笔误导致在生产环境中的bug,非常隐蔽不容易被发现,排除这样的错误经常要花上半天的时间或者更长。

   解决这个问题的办法是通过在编辑后执行文档Schema校验的方式来校验文档的正确行,校验方式有两种一种是DTD,另外一种方式是Schema,就是XSD(XML Schema Definition)这种方式对XML校验更加完善,可以对属性进行类型校验。

 

   简单起见,对schema.xml 利用DTD方式进行校验。以下是我针对solr的schema文件写DTD文件:

 

<!ELEMENT schema (types+,fields+,uniqueKey,defaultSearchField,similarity?,solrQueryParser,copyField*)>

<!ATTLIST schema name CDATA #REQUIRED>
<!ATTLIST schema version CDATA #REQUIRED>

<!ELEMENT types (fieldType+)>
<!ELEMENT fieldType (analyzer*)>

<!ATTLIST fieldType name CDATA #REQUIRED>
<!ATTLIST fieldType class CDATA #REQUIRED>
<!ATTLIST fieldType positionIncrementGap CDATA #IMPLIED> 
<!ATTLIST fieldType sortMissingLast (true|false) "true">
<!ATTLIST fieldType omitNorms (true|false) "true">
<!ATTLIST fieldType precisionStep CDATA #IMPLIED>
<!ATTLIST fieldType autoGeneratePhraseQueries (true|false) #IMPLIED>
<!ATTLIST fieldType tokenized (true|false) #IMPLIED>
<!ATTLIST fieldType omitTermFreqAndPositions (true|false) #IMPLIED>



<!ELEMENT analyzer (tokenizer*,filter*)>
<!ATTLIST analyzer 
  type (index|query) #IMPLIED
  class CDATA        #IMPLIED>

<!ELEMENT tokenizer EMPTY>
<!ATTLIST tokenizer 
   class CDATA #REQUIRED
   group CDATA #IMPLIED
   pattern CDATA #IMPLIED>

<!ELEMENT filter EMPTY>
<!ATTLIST filter class CDATA #REQUIRED>

<!ELEMENT uniqueKey (#PCDATA)>
<!ELEMENT defaultSearchField (#PCDATA)>

<!ELEMENT similarity (str*)>
<!ATTLIST similarity class CDATA #REQUIRED>

<!ELEMENT str (#PCDATA)>
<!ATTLIST str name CDATA #REQUIRED>


<!ELEMENT solrQueryParser EMPTY>
<!ATTLIST solrQueryParser defaultOperator (OR|AND) #REQUIRED>

<!ELEMENT fields (field|dynamicField)+>
<!ELEMENT field  EMPTY>
<!ATTLIST field  name CDATA #REQUIRED>
<!ATTLIST field  type CDATA #REQUIRED>
<!ATTLIST field  indexed (true|false) #IMPLIED>
<!ATTLIST field  stored (true|false) #IMPLIED>
<!ATTLIST field  multiValued (true|false) #IMPLIED>
<!ATTLIST field  required (true|false) #IMPLIED>
<!ATTLIST field  default CDATA #IMPLIED>

<!ELEMENT dynamicField EMPTY>
<!ATTLIST dynamicField  name CDATA #REQUIRED>
<!ATTLIST dynamicField  type CDATA #REQUIRED>
<!ATTLIST dynamicField  indexed (true|false) #IMPLIED>
<!ATTLIST dynamicField  stored (true|false) #IMPLIED>
<!ATTLIST dynamicField  multiValued (true|false) #IMPLIED>
<!ATTLIST dynamicField  required (true|false) #IMPLIED>

<!ELEMENT copyField EMPTY>
<!ATTLIST copyField  source CDATA #REQUIRED>
<!ATTLIST copyField  dest CDATA #REQUIRED>
 

 

 然后就可以用这个dtd来校验XML文件了,以下是一个schema XML文件样例:

<?xml version="1.0" ?>
 <!DOCTYPE schema SYSTEM  "solrschema.dtd">
<schema name="example core" version="1.1">
	<types>
		<fieldType name="string" class="solr.TextField"
			sortMissingLast="true"></fieldType>

		<fieldType name="int" class="solr.TrieIntField"
			precisionStep="0" positionIncrementGap="0" />

		<fieldType name="tlong" class="solr.TrieLongField"
			precisionStep="8" omitNorms="true" positionIncrementGap="0" />

		<fieldType name="sint" class="solr.SortableIntField"
			sortMissingLast="true" omitNorms="true" />

		<fieldType name="slong" class="solr.SortableLongField"
			sortMissingLast="true" omitNorms="true" />

		<fieldType name="string_ws" class="solr.TextField"
			positionIncrementGap="100">
			<analyzer>
				<tokenizer class="solr.WhitespaceTokenizerFactory" />
			</analyzer>
		</fieldType>

		<fieldType name="string_sd" class="solr.TextField"
			sortMissingLast="true" omitNorms="true">
			<analyzer type="index">
				<tokenizer class="solr.StandardTokenizerFactory" />
				<filter class="solr.ChineseFilterFactory" />
				<filter class="solr.LowerCaseFilterFactory" />
			</analyzer>
			<analyzer type="query">
				<tokenizer class="solr.StandardTokenizerFactory" />
				<filter class="solr.ChineseFilterFactory" />
				<filter class="solr.LowerCaseFilterFactory" />
			</analyzer>

		</fieldType>

		<fieldType name="tint" class="solr.TrieIntField"
			precisionStep="8" omitNorms="true" positionIncrementGap="0" />
		<fieldType name="tfloat" class="solr.TrieFloatField"
			precisionStep="8" omitNorms="true" positionIncrementGap="0" />
		<fieldType name="sfloat" class="solr.SortableFloatField"
			sortMissingLast="true" omitNorms="true" />

	</types>

	<fields>
		<field name="id" type="slong" indexed="true" stored="true"
			multiValued="false" required="true" />
		<field name="userId" type="slong" indexed="true" stored="true"
			multiValued="false" />
		<field name="userNick" type="string" indexed="true" stored="true"
			multiValued="false" />
		<field name="title" type="string_sd" indexed="true" stored="true"
			multiValued="false" />
		<field name="contentKey" type="string" indexed="true" stored="true"
			multiValued="false" />
		<field name="coverPicpath" type="string" indexed="true" stored="true"
			multiValued="false" />
		<field name="itemId" type="string" indexed="true" stored="true"
			multiValued="false" />
		<field name="gmtCreated" type="slong" indexed="true" stored="true"
			multiValued="false" />
		<field name="gmtModified" type="slong" indexed="true" stored="true"
			multiValued="false" />
		<field name="tag" type="string_sd" indexed="true" stored="true"
			multiValued="false" />
		<field name="aScore" type="sfloat" indexed="true" stored="true"
			multiValued="false" />
		<field name="count" type="int" indexed="true" stored="true"
			multiValued="false" />
		<field name="feedId" type="string" stored="true" multiValued="false" />
		<field name="summary" type="string_sd" indexed="true" stored="true"
			multiValued="false" />
		<field name="status" type="int" indexed="true" stored="true"
			multiValued="false" />

		<dynamicField name="*-t" type="text_com" stored="false"
			indexed="true" />

	</fields>

	<uniqueKey>id</uniqueKey>
	<defaultSearchField>id</defaultSearchField>

	<similarity class="com.taobao.terminator.core.solrx.PayloadSimilarity">
		<str name="func">max</str>
	</similarity>

	<solrQueryParser defaultOperator="OR" />
	<copyField source="prov" dest="location" />
</schema>

 

 

 

写一个java的单元测试类来校验,XML的正确性:

 

import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * @author 百岁(baisui@taobao.com)
 * @date 2012-11-28
 */
public class TestSchemaDTDValidate extends TestCase {
	private final static DocumentBuilderFactory factory = DocumentBuilderFactory
			.newInstance();
	static {
		factory.setValidating(true);
	}

	public void testFile1() {

		Assert.assertTrue("schema3.xml", XMLValidateDTD("schema3.xml"));

	}

	public boolean XMLValidateDTD(String file) {

		MyHandler mh = new MyHandler();
		InputStream inputStream = null;
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			builder.setErrorHandler(mh);

			inputStream = this.getClass().getResourceAsStream("/" + file);

			builder.parse(inputStream);
		} catch (Exception e) {

			Assert.assertFalse(e.getMessage(), true);

			return false;
		} finally {
			try {
				inputStream.close();
			} catch (Throwable e) {

			}
		}
		return mh.validate;
	}

	static class MyHandler extends DefaultHandler {
		String errorMessage = null;

		private boolean validate = true;

		public void error(SAXParseException e) throws SAXException {
			errorMessage = e.getMessage();

			System.out.println(errorMessage + " linenumber:"
					+ e.getLineNumber());

			Assert.assertFalse(errorMessage, true);

			validate = false;

		}

		public void fatalError(SAXParseException e) throws SAXException {
			errorMessage = e.getMessage();
			System.out.println(errorMessage);
			validate = false;
			Assert.assertFalse(errorMessage + " linenumber:"
					+ e.getLineNumber(), true);
		}
	}

}

 

 

使用DTD来校验XML有以下不足:

 

  1. 子元素在排列顺序上有限制,是实际的xml文档中,定义的元素节点,必须要按照DTD中定义的顺序,哪怕这几个子元素在逻辑上并没有逻辑以来关系,比如,以上xml中<uniqueKey/>必须在<defaultSearchField/> 之前,如果不是这样的话校验XML过程中就会校验失败。
  2. 不能对节点属性的类型进行校验,比如,fieldType节点的precisionStep属性必须为数字,在实际中如果用户填写了非数字的字符作为的属性的话,校验也会通过的。这样就会发生潜在的错误。
虽然现在使用DTD有以上不足,但是相对以前完全没有校验机制来说已经进步一大截了,可以帮助我们规避掉很大一部分不必要的麻烦问题。如果想要弥补以上不足的话可以尝试一下XSD的校验机制。

 

 

 

分享到:
评论

相关推荐

    solrconfig.xml和schema.xml说明

    ### Solrconfig.xml 和 Schema.xml 说明 #### Solrconfig.xml 概述 Solrconfig.xml 是 Apache Solr 的核心配置文件之一,主要用于定义 Solr 实例如何处理文档的索引与查询请求。该文件中包含了多种配置项,用于...

    solr schema solrconfig 配置文件解析

    Solr,作为一款开源的全文搜索引擎,其核心配置文件包括`schema.xml`和`solrconfig.xml`,它们是Solr工作方式的基础。在深入理解这两个文件之前,我们需要先了解Solr的基本架构。 **1. Solr架构简介** Solr采用...

    解决solr启动404问题

    Solr的核心配置文件是`solrconfig.xml`和`schema.xml`,它们定义了索引的结构和处理查询的方式。 当你遇到404错误,首先检查Solr是否成功启动。查看日志文件(通常是`logs/solr.log`)以获取更详细的错误信息。如果...

    使用xml更新solr索引

    在Solr中,XML格式是用于向索引添加、更新或修改文档的主要方式。Solr索引是一个存储和...确保在`schema.xml`中正确配置了字段类型和设置,以支持所需的更新操作,并且要理解不同的提交选项,以平衡性能和数据一致性。

    solr_solr_

    在本配置文件中,我们关注的是`manageschema`配置,这是Solr用来管理其Schema XML的一种工具,用于定义字段类型和字段,以及它们如何被索引和搜索。 在Solr中,Schema是核心组件之一,它定义了文档的结构和处理方式...

    schema.xml说明

    ### Solr中的schema.xml详解 在Solr搜索服务器中,`schema.xml` 文件扮演着核心配置文件的角色,它定义了索引字段、字段类型以及其他与数据结构相关的设置。正确理解和配置`schema.xml`对于实现高性能的全文检索...

    solr单机部署

    第七步:告诉Solr服务器Solrhome的位置,需要修改Solr工程的web.xml文件。 第八步:启动Tomcat。 3. 配置业务字段 在Solr中默认是中文分析器,需要手工配置。配置一个FieldType,在FieldType中指定中文分析器。Solr...

    solr4.9与tomcat8,tomcat7整合

    - 如果启动后出现错误,如`Could not load core configuration`或`ConfigSolr - /root/solr/home/solr.xml does not exist`,可能是因为`solr.xml`配置不正确。检查`solr.xml`文件,确保`docBase`和`solr/home`的...

    solr与tomcat整合

    要在Tomcat中配置Solr,需要修改Tomcat的`conf/Catalina/localhost`目录下的`solr.xml`文件。设置`docBase`属性为`E:\ruanjian\lucene-3.6.2\solr\server\solr`,这是你的Solr应用的路径。 5. **配置Context**: ...

    Solr安装与配置

    对于分词搜索的配置,首先需要解压 Solr 的 war 包到一个新的目录,比如 `E:\solr`,然后在 Solr 的 `example\multicore` 目录下创建或修改 `schema.xml` 文件,定义用于分词索引的字段。这些字段名需要与后续分词...

    solr7.2.1 ik

    2. **配置Solr Schema**:在Solr的Schema.xml文件中,需要为需要分词的字段指定`&lt;analyzer&gt;`标签,并在其中使用IK分词器。例如: ```xml &lt;fieldType name="text_ik" class="solr.TextField" positionIncrementGap=...

    solr安装配置(单核、多核)

    4. 使用 Solr 示例的 `multicore` 目录中的 `solr.xml` 替换 Solr 根目录下的 `solr.xml` 文件,确保文件中包含了所有核心的定义。 5. 重新启动 Tomcat,现在你可以通过访问 `http://localhost:8888/solr` 来管理多...

    solr6 增量导入demo

    2. 配置Solr schema:确保Solr的Schema.xml文件包含了需要索引的所有字段,包括用于增量检测的字段。 3. 启用DeltaImport:在Solr的请求处理器中启用DeltaImport,以便能够通过HTTP请求触发增量导入。 四、定时...

    solr(solr-9.0.0.tgz)

    在使用Solr-9.0.0时,你需要根据业务需求创建或修改配置文件,如`solrconfig.xml`和`schema.xml`,定义索引的字段类型和字段。然后可以通过POST请求将数据导入Solr,Solr会自动进行分词、建立倒排索引等操作,从而...

    solr4.7服务搭建

    1. **修改 schema.xml 文件**:打开 `D:\solr\home` 目录下的 schema.xml 文件,增加或修改以下字段类型定义: ```xml &lt;fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100"&gt; ...

    ikanalyzer-solr8.4.0_solr8_solr_ikanalyzer_中文分词_

    3. **配置Schema.xml**:在 Solr 的 schema.xml 文件中,我们需要定义字段类型(FieldType)并指定使用 ikanalyzer。例如,可以创建一个名为 `text_ik` 的字段类型,并设置其`analyzer_class`属性为 `org.apache....

    solr中文分词jar包ik-analyzer 含class配置 ik-analyzer-7.5.0

    2. **配置Solr schema.xml**:在Solr的schema.xml文件中,定义字段类型(fieldType),并指定使用Ik Analyzer。例如: ```xml &lt;fieldType name="text_ik" class="solr.TextField" positionIncrementGap="100"&gt; ...

    Window下Solr1.4安装部署

    - **Schema.xml覆盖**:覆盖`D:\solr-tomcat\solr\conf\schema.xml`文件,示例内容如下: ```xml &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;schema name="example" version="1.1"&gt; ...

    Solr3.5整合Tomcat

    3. **修改 Solr 配置**:回到 Solr 的安装目录,打开 `solr/conf/solrconfig.xml` 和 `solr/solr.xml` 进行必要的配置。根据你的需求,可能需要调整索引存储方式、请求处理器、查询分析器等设置。 4. **启动 Tomcat...

Global site tag (gtag.js) - Google Analytics