關於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命令,然後又會出現別的錯誤,就這樣,你就知道他的執行順序了,我不知道我這樣的方法合理不合理,如果已經有大哥明確了他的原理請指教!!謝謝。
發佈了44 篇原創文章 · 獲贊 12 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章