1. 程式人生 > >全文索引----建立多表solr索引

全文索引----建立多表solr索引

        我們在使用solr作為索引伺服器時,通常會將多個表的多個欄位作為聯合索引,對多個錶快速的資料查詢也是solr伺服器高效率的體現。這片文章介紹下如何基於多個數據表建立索引。
        一 無關聯多表建立索引
        1.1 資料庫準備

        我們使用任意的兩個表作為資料來源,這兩個表可以屬於一個數據庫,也可以屬於不同的資料庫,如果使用兩個資料庫,則需要兩個資料來源連線字串,我們這裡使用同一個庫的兩個表作為示例。

        兩個表結構如下:

        表一:

       表二:

        1.2 配置data-config.xml
        我們之前已經配置好了solr伺服器,所以只需要修改資料來源配置檔案和索引配置檔案即可。資料來源檔案配置如下:

<dataSource name="jfinal_demo" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" 
url="jdbc:mysql://192.168.21.20:3306/jfinal_demo" user="root" password="123456" batchSize="-1" />
  	<document name="testDoc">
		<entity name="user" dataSource="jfinal_demo" pk="id" query="select * from user">
			<field column="id" name="userId"/>
     	<span style="white-space:pre">	</span><field column="userName" name="userName"/>
			<field column="userAge" name="userAge"/>
			<field column="userAddress" name="userAddress"/>
		</entity>
		<entity name="role" pk="id" query="select * from role" >
			<field column="id" name="roleId"/>
			<field column="name" name="roleName"/>
		</entity>
	</document>

        說明:dataSource標籤是資料庫連線字串,name屬性作為連線字串識別符號,type是資料來源型別,我們這裡選用jdbc資料來源JdbcDataSource,drive是資料驅動,選擇MySQL資料驅動,URL是資料庫連線字串。
       document標籤下新增我們需要索引的資料,entity代表一個實體,name屬性用來區分不同的實體,pk屬性時資料表的主鍵,這個屬性必須要和資料表主鍵一致,不能修改。
        field標籤是需要索引的欄位,column是資料列,name是別名。
        注意:設定主鍵是需要特別注意,如果兩個表的主鍵資料一致,則後面的索引會覆蓋掉前邊的索引,但是很多情況是,我們使用自增長的資料作為主鍵,這樣不可避免的就會產生主鍵一致情況,百度了一下,解決方法大致有兩種:
        1 主鍵使用uuid格式,從根本上避免逐漸一致情況,並且比較安全。
        2 去掉schema.xml中uniqueKey屬性,或者在表中新建一個欄位作為uniqueKey屬性。
        1.3 配置schema.xml
        將表中所有需要索引的欄位新增到檔案中fields標籤下,注意,相同的欄位就不想要添加了,例如ID。配置如下:



        1.4 重啟solr服務,測試。
  
        二 關聯表建立索引
        有關聯表建立索引的步驟和無關聯表一致,只是data-config.xml配置不同,具體如下。

        2.1 資料庫結構圖如下:

        2.2 data-config.xml配置如下:

<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.21.20:3306/jrkj_java" user="root" password="123456" batchSize="-1" />
	<document name="testDoc">
		<entity name="tj_student" pk="id" query="SELECT id,nickName,isDelete FROM tj_student where isDelete = 0 and applyTeacherState = 1 and isTeacher = 1">
			<field column="id" name="id"/>
			<field column="nickName" name="nickName"/>
			<field column="isDelete" name="isDelete"/>
			<entity name="tj_course" pk="id" query="select id,courseName from tj_course where isDelete=0 and courseAuditState=1 and studentId='${tj_student.id}'">
				<field column="id" name="courseId"/>
				<field column="courseName" name="courseName"/>
 			</entity>
			<entity name="tj_userfield" pk="id" query="select fieldId,studentId from tj_userfield where isDelete = 0 and userFieldType = 1 and studentId = '${tj_student.id}'">
				<field column="fieldId" name="fieldId"/>
				<field column="studentId" name="studentId"/>
				<entity name="tj_field" pk="id" query="select fieldName,pointWord from tj_field where isDelete = 0 and id='${tj_userfield.fieldId}'">
					<field column="fieldName" name="fieldName"/>
					<field column="pointWord" name="pointWord"/>
				</entity>
			</entity>
			<entity name="tj_userIndustry" pk="id" query="select industryId from tj_userindustry where isDelete = 0 and userIndustryType = 1 and studentId = '${tj_student.id}'">
				<field column="industryId"/>
				<entity name="tj_industry" pk="id" query="select industryName from tj_industry where isDelete = 0 and id = '${tj_userIndustry.industryId}'">
					<field column="industryName" name="industryName"/>
				</entity>
			</entity>
		</entity>
  </document>

        除了上面這種形式,官網給了第二種方式,結構如下:

<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.21.20:3306/jrkj_java" user="root" password="123456" batchSize="-1" />
	<document name="testDoc">
		<entity name="tj_student" pk="id" query="SELECT id,nickName,isDelete FROM tj_student where isDelete = 0 and applyTeacherState = 1 and isTeacher = 1">
			<entity name="tj_course" pk="id" query="select id,courseName from tj_course where isDelete=0 and courseAuditState=1 and studentId='${tj_student.id}'">
 			</entity>
			<entity name="tj_userfield" pk="id" query="select fieldId,studentId from tj_userfield where isDelete = 0 and userFieldType = 1 and studentId = '${tj_student.id}'">
				<entity name="tj_field" pk="id" query="select fieldName,pointWord from tj_field where isDelete = 0 and id='${tj_userfield.fieldId}'">
				</entity>
			</entity>
			<entity name="tj_userIndustry" pk="id" query="select industryId from tj_userindustry where isDelete = 0 and userIndustryType = 1 and studentId = '${tj_student.id}'">
				<entity name="tj_industry" pk="id" query="select industryName from tj_industry where isDelete = 0 and id = '${tj_userIndustry.industryId}'">
				</entity>
			</entity>
		</entity>
  </document>

        2.3 配置schema.xml

        配置如下:

        2.4 重啟solr服務,測試。

        三 總結

        多表索引是solr伺服器最常見的索引方式,因為索引關鍵字很容易重複,特別是主鍵容易出錯,所以建立索引時需要非常小心。

宣告:如無特殊宣告,本系列部落格以solr-4.7.2版本為例,如有錯誤,敬請斧正。