关于solr中data-config.xml里面的各种Query的执行过程的学习

如有转载,请注明出处,谢谢合作!         

 

solr中的data-config.xml这个配置文件大家都知道,但是我对其中query,deltaQuery,parentDeltaQuery,deletedPkQuery的执行过程有点迷惑,所以自己探索学习了一下,我先说自己得出来的结论(其中关于deletedPkQuery是怎么执行的任然不解),然后说明得出结论的方法。

 

 

对于data-config.xml这个配置文件,我举个简单的例子:

<dataConfig>

            <dataSource>

              ........(这里是配置数据源的)

            </dataSource>

            <document>

                       <entity   name="member"  pk="id"   query="select id, ...... from Member where isDeleted=false"

                                                                                       deletedPkQuery="select id , ......   from Member where isDeleted=true"

                                                                                        deltaQuery="selected id from Member where lastModifyTime>'${dataimporter.last_index_time}'  ">

                                             <entity   name="connection" pk="...."  query="......."

                                                                                                deltaQuery="......."

                                                                                                 parentDeltaQuery="........">

                                             <\entity>

 

                                             <entity   name="groupMember" pk="...."  query="......."

                                                                                                deltaQuery="......."

                                                                                                 parentDeltaQuery="........">

                                             <\entity>

 

                       <\entity>

            </document>

</dataConfig>

(配置文件中的isDeleted是我表中的一个字段,是用来标记删除的,true表示该条数据被删除,false表示没有被删除)

上面的配置文件只是列出了大致的结构。

 

我通常都是用2种http请求:一种就是fullImport,还有一种就是deltaImport。

如果是fullImport,那么就执行上面配置文件中的query语句(其他的语句不执行),并且主实体和子实体是嵌套的关系,即主实体query得到的每一行数据都将要被子实体拿去执行。

如果是deltaImport,那么执行顺序是这样的:

(简单起见,首先假设现在没有要更新的数据)首先从子实体的detaQuery开始,如上面配置文件的connection实体,先执行该实体的detaQuery,发现没有数据要更新(那么就不会执行parentDeltaQuery),然后在继续执行下一个实体groupMember里面的deltaQuery,发现也没有要更新的数据。最后执行deletedPkQuery。

首先到此为止,我觉得,当我向solr服务请求deltaImport命令的时候,它就会先执行子实体的deltaQuery(我测试的例子里面只有2层,但我相信,如果还有更多层,那么它还是会先执行子实体的deltaQuery)

你有可能会问:当我请求deltaImport命令的时候,难道只有deltaQuery和deletedPkQuery被执行吗?那parentDeltaQuery和query就不执行了吗?

 

我之前说了,那是在没有数据要更新的时候,它是这样一种执行顺序(当然,如果有数据要更新,它还是这种执行顺序,但情况会不一样)。

当任何一个表里面的数据有更新时。我请求delteImport命令时,它任然按照上面讨论的那种顺序执行,比如说,我在执行connection实体里面的deltaQuery时,发现了一条数据被更新了,那么这时,parentDeltaQuery就会根据这条数据的id查出它的父实体的id,我的理解是,子实体会将这变化了的数据的id告知他的父实体(请注意:deltaQuery和parentDeltaQuery也是一种嵌套关系,即deltaQuery执行的到的每一条数据都将被parentDeltaQuery执行,这在solr wiki里面有介绍)。当执行完了parentDeltaQuery后,他将继续执行下一个实体connection里面的deltaQuery,假如发现了有数据更新了,那么也一样要执行parentDeltaQuery。

 

综上所述,当有deltaImport请求的时候,他都是先执行deltaQuery,如果在该实体中没有发现要更新的数据,那就不执行parentDeltaQuery,直接执行下一个实体里面的deltaQuery了,如果发现了更新了数据,那么就执行parentDeltaQurery,然后继续下一个实体....

 

你可能会问:“照你这么说,当所有的子实体执行完了,各个实体里面的parentDeltaQuery找到的数据都到哪里去了?你不是说他会提交给相应实体的父实体吗?那这么提交的呢?”

对于第一个问题,“找到的数据到哪里去了?”,我不太确定,因为我没有看过这部分的源代码,但在测试的过程中给我的感觉是这样子的:可能会有这样的一个堆栈,把每一个实体找到的更新了的数据都压到这个堆栈里面,等所有的子实体都执行完了之后,然后执行主实体中的deletedPkQuery(为什么这时会执行这句?这是我在上面讨论过的,就是这样。先不要问我这句是怎么执行的!),然后在最后执行主实体的Query,这时主实体的query就依次取出堆栈里面的id,每次取到一个id,就嵌套执行所有子实体的query。这时就和你请求fullImport命令的时候的情况差不多了。

 

对于第二个问题:“你不是说他会提交给相应实体的父实体吗?那这么提交的呢?”

我想说的是,当我所谓的“堆栈”里面充满了更新了的数据的id的时候,这时就轮到主实体的query来这里取数据了,这时我发现,我的主实体里面的query的select语句被瞧瞧的改变了,比如上面data-config.xml里面主实体是member,他的query="select id, ...... from Member where isDeleted=false"在你看不见的地方改成了query="select id, ...... from Member where isDeleted=false and id=13" 而这里面的id为13的那条数据正是更新了的数据的id。所以我觉得,父实体里面的query就是通过把“堆栈”里面的id取出来,然后把“我写的query语句”拼接上这个id,然后向下一级一级执行query语句的。

 

假如你够细心,你一定还会问我:“那主实体里面的deletedPkQuery是不是也是和他的Query一样,被拼接上了一个id,然后将之从索引里面删除?”

唉~~问题就出在这里啊,我在测试的时候,预期也是以为被拼接上了一个id,可是结果没有,我就郁闷了,当子实体数据有更新的时候,他是怎么拿到这些数据的id然后将他的索引删除的呢?我也不知道,在网上找了一些资料,发现讲的最详细的就是这位大哥的博客了:http://blog.sina.com.cn/s/blog_539d361e0100nca5.html

可我还是不太明白,请知道的大哥解释一下!!!!

 

最后说明一下我是怎样得出这个结论的?

我的方法就是让这个data-import.xml出错,最简单的我将上面的配置文件做如下修改:

<document>

                       <entity   name="member"  pk="id"   query="select id, ...... from Member where isDeleted=false1111"

                                                                                       deletedPkQuery="select id , ......   from Member where isDeleted=true2222"

                                                                                        deltaQuery="selected id from Member where lastModifyTime>'${dataimporter.last_index_time}'  3333">

                                             <entity   name="connection" pk="...."  query=".......4444"

                                                                                                deltaQuery=".......5555"

                                                                                                 parentDeltaQuery="........6666">

                                             <\entity>

 

                                             <entity   name="groupMember" pk="...."  query=".......7777"

                                                                                                deltaQuery=".......8888"

                                                                                                 parentDeltaQuery="........9999">

                                             <\entity>

 

                       <\entity>

            </document>

 

我就是在每一条语句后面编号,这明显是有错的,当我进行deltaImport命令请求时,在命令提示符里面就会出现相关的错误报告,你去找第一个错误,他会说:“deltaQuery=".......5555”无法执行,那么你就知道他先执行的哪句?然后你在去掉”5555”,重启solr服务,继续请求deltaImport命令,然后又会出现别的错误,就这样,你就知道他的执行顺序了,我不知道我这样的方法合理不合理,如果已经有大哥明确了他的原理请指教!!谢谢。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值