solr杂记

solr版本4.10.2

solr删除全部索引数据:选择Document Type为XML类型
这里写图片描述

<delete><query>*:*</query></delete><commit/>

从数据库导入多表到solr中,由于solr规定每一条记录必须有一个主键值,用来唯一标识一条索引的记录,默认是使用id字段来作主键,所以多表情况下会出现id重复,导致记录被覆盖,因此将solr的id设为自生成uuid,由solr维护。
1、在schema.xml文件中添加:

<fieldType name="uuid" class="solr.UUIDField" indexed="true" />

2、设置主键id的type为uuid:

<field name="id" type="uuid" indexed="true" stored="true" required="false" multiValued="false" />

3、在solrconfig.xml文件中添加:

<updateRequestProcessorChain name="uuid">  
    <processor class="solr.UUIDUpdateProcessorFactory">  
        <str name="fieldName">id</str>  
    </processor>  
    <processor class="solr.RunUpdateProcessorFactory" />  
</updateRequestProcessorChain>

4、将此requestHandler中的defaults修改为如下:

<requestHandler name="/update" class="solr.UpdateRequestHandler">  
     <lst name="defaults">  
          <str name="update.chain">uuid</str>  
     </lst>  
  </requestHandler>

5、注释下面的代码,不然会报异常:

<searchComponent name="elevator" class="solr.QueryElevationComponent" >  
  <str name="queryFieldType">string</str>  
  <str name="config-file">elevate.xml</str>  
</searchComponent>

6、将<str name="update.chain">uuid</str>加入到数据导入的部分:

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
     <lst name="defaults">
        <str name="config">db-data-config.xml</str>
        <str name="update.chain">uuid</str>
     </lst>
  </requestHandler>

这样,在db-data-config.xml中就不需要指定solr中id对应的column。

这是我的多数据源配置,对于oracle数据库要注意字段大写:

<?xml version="1.0" encoding="UTF-8" ?>  
<dataConfig>
    <dataSource 
        name="mysql"
        type="JdbcDataSource"
        driver="com.mysql.jdbc.Driver"
        url="jdbc:mysql://127.0.0.1:3306/youmanagerdb"
        user="root"
        password="root"/>
    <dataSource 
        name="oracle"
        type="JdbcDataSource"
        driver="oracle.jdbc.driver.OracleDriver"
        url="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"
        user="flyy3"
        password="flyy3"/>

    <document>
        <entity name="bill" dataSource="mysql" query="select mybill_id,memo,money from tbl_mybill">
            <field column="mybill_id" name="bill_id" />
            <field column="memo" name="bill_memo" />
            <field column="money" name="bill_money" />
        </entity>

        <entity name="schedulejob" dataSource="mysql" query="select job_id,memo,cron_expression from tbl_schedulejob">
            <field column="job_id" name="schedulejob_id" />
            <field column="memo" name="schedulejob_memo" />
            <field column="cron_expression" name="schedulejob_cron" />
        </entity>

        <entity name="cpws" dataSource="oracle" transformer="ClobTransformer" query="select ID, AJLB, NR from cpws where rownum&lt;200">
            <field column="ID" name="cpws_id" />
            <field column="AJLB" name="cpws_ajlb" />
            <field column="NR" name="cpws_nr" clob="true"/>
        </entity>

    </document>
</dataConfig>

对于clob字段,需要加上transformer="ClobTransformer"clob="true"

如果涉及到多表的,使用别名作为name,如下(之前使用表名+字段名作为name,就无法导入数据):

<?xml version="1.0" encoding="UTF-8" ?>  
<dataConfig>
    <dataSource 
        name="oracle"
        type="JdbcDataSource"
        driver="oracle.jdbc.driver.OracleDriver"
        url="jdbc:oracle:thin:@//192.168.30.172:1521/orcl"
        user="flyy3"
        password="flyy3"/>

    <document>
        <entity name="flqw" dataSource="oracle" transformer="ClobTransformer" query="SELECT
    FLQWJBXX.ID as FID, FLQWJBXX.MC as FMC, FLQWJBXX.BBH as FBBH, FLQWJBXX.BBBM as FFBBH, FLQWJBXX.BBRQ as FBBRQ, FLQWJBXX.SSRQ as FSSRQ, 
    FLQWJBXX.YXX as FYXX, FLQWJBXX.FLFL_ID as FLFLID, FLFL.MC as FLFLMC, FLFL.GFLFL as FGFLFL, FLFL.SJFLFLID as FSJFLFLID, FLQWNR.NR as FNR
    FROM FLQWJBXX, FLFL, FLQWNR WHERE
    FLQWJBXX.ID = FLQWNR.ID AND FLQWJBXX.FLFL_ID = FLFL.ID">
            <field column="FID" name="flqw_flqwjbxx_id" />
            <field column="FMC" name="flqw_flqwjbxx_mc" />
            <field column="FBBH" name="flqw_flqwjbxx_bbh" />
            <field column="FBBBM" name="flqw_flqwjbxx_bbbm" />
            <field column="FBBRQ" name="flqw_flqwjbxx_bbrq" />
            <field column="FSSRQ" name="flqw_flqwjbxx_ssrq" />
            <field column="FYXX" name="flqw_flqwjbxx_yxx" />
            <field column="FLFLID" name="flqw_flqwjbxx_flfl_id" />
            <field column="FLFLMC" name="flqw_flfl_mc" />
            <field column="FGFLFL" name="flqw_flfl_gflfl" />
            <field column="FSJFLFLID" name="flqw_flfl_sjflflid" />
            <field column="FNR" name="flqw_flqwnr_nr" clob="true"/>
        </entity>
    </document>
</dataConfig>

solr的join用法:
因为工作中需要把多张表放在solr中加快查询速度,同时这几张表又涉及到多表关联查询,在网上看到说join可以做到这点。但关于join的资料很少,规则也不是很明白,下面是我个人的一点理解:

sq.set("q", "{!join from=id to=name}title:2"); 

相当于sql语句:

select * from tbl1 where name in (select id from tbl2 where title = 2)
sq.set("q", "{!join from=id to=title fromIndex=core3}name:apple");

相当于slq语句:

select f.* from tbl4 f inner join tbl3 t on t.id = f.title where t.name = 'apple'

tbl3相当于core3,tbl4相当于core4

在linux上部署solr时,遇到一个小坑:
我在windows上部署,是在tomcat的start.bat中指定solr_home的位置。但是在linux上并不使用start.bat,而是start.sh,在这个文件我不知道怎么指定solr_home的位置,于是就在solr的web.xml中加入如下代码:

<env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>/data/solr/solr_home</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
</env-entry>

在做不包含查询时,使用的是:

-flqw_flqwnr_nr:美国 AND -flqw_flqwnr_nr:相关

网上的方式:

flqw_flqwnr_nr:* NOT 美国 NOT 相关

这种方式失效。

其他查询的写法也相似:

flqw_flqwnr_nr:美国 OR flqw_flqwnr_nr:中国
flqw_flqwnr_nr:(美国 OR 中国)

如果要让搜索字在查询时不分词,就用"来包裹搜索字,如下:

params.set("q", "flqw_flqwnr_nr:"+'"'+"全国人民代表大会"+'"');

项目中需要根据查询条件和类别获取各个分类的查询结果数量,我使用的是group分组查询,在查询条件时,一开始我设置的是如果用户没有输入搜索词,那么就

params.set("q", "nr:*");

结果查询速度相当慢,然后根据逻辑改成了

params.set("q", "*:*");

速度就快了很多。

网上提到solr索引这块,可以用int或long类型的,就不要用string,原因是整型的索引存储空间一般比字段串所占的存储索引空间要小;整型的查找比较速度比字段串类型要快。

关于solr分页这块,假如数据有100万条,直接查询最后一页,速度会相当慢,这就类似于mysql中的分页

select * from table where column between 1 and 2 order by id limit 0, 10;
select * from table where column between 1 and 2 order by id limit 1000000, 10;

mysql在执行时,会扫过满足结果的前start行的记录,然后才读取len行的数据,如果start特别大,会非常慢。
在solr中也会出现这种情况,现在的思路是:
假如是通过order by进行id asc排序,对于100万条数据,如果用户查询的是前50万条,就正常查询;如果用户查询的是后半部分数据,就id desc排序,根据总条数和用户点击的页码计算出逆序排序后的起始数,获得查询结果后再倒序回来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值