前段時間我一直在參與中臺業務的solr服務,因爲也是第一次接觸,在學習的過程中做了一些筆記,正好在這裏做一個記錄。
我們這裏就直接從managed-schema說起。
managed-schema文件主要就是用來配置Field,Field相當於Java中的類屬性,你可以給它配置各種屬性,比如是否需要顯示呀,是否可以作爲被檢索的索引呀等等。
我們找一個來看看都有哪些屬性。
<field name="id" type="text_ik" indexed="true" stored="true" multiValued=”true”/>
1.name:是查詢時的名稱。
2.type:字段類型。
3.indexed:是否爲索引字段。(true:是。false:否)solr控制檯使用df當作查詢域。注:indexed=true,即可以使得一個filed當作搜索條件。indexed=false,即此field無法被當作搜索的條件。
我們找一個indexed=true的字段試試,就用id吧。
顯然,我們找到一個檢索結果。從第一張圖裏我們可以看到,url的indexed=false,所以應該是無法用url檢索消息的。我們就直接用這條數據的url作爲檢索的條件,看能不能檢索到該條數據。
顯然,啥玩意也沒有。
4.stored:是否存儲。solr控制檯使用fl當作查詢結果。
注:stored=true,則此filed可以作爲查詢結果。
stored=false,則即使你有符合的數據,你也看不到該field。
從上圖可知,province字段 indexed=true,但是stroed=false。這就說明,你可以用province作爲檢索條件,但是你的檢索結果不會顯示出來。我們來試試。(我們的province用的是編碼,以山西爲例)
ok,從以上的查詢結果,我們可以看出來,province的確可以作爲檢索條件,但是在檢索出來的結果中並不會顯示province這個字段。
5.multiValued:是否多值(一般配合copyFiled使用)
如果對filed域的其它屬性感興趣,可以參考:https://www.cnblogs.com/langfanyun/p/5868182.html。這篇文章將所有的屬性弄成了表格,我覺得ok。
這裏放一張縮略:
二、copyField 複製域
三、multivalued 多值
<field name="allcontent" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="title" dest="allcontent" />
<copyField source="orgtitle" dest="allcontent" />
<copyField source="content" dest="allcontent" />
從上文看出allcontent區域,是title、orgtitle、content三個的集合,無論搜索title、orgtitle、content任意一個,都能通過allcontent搜索出來。
其中allcontent 本身也是一個域,也可存儲信息。其最終結果爲 title+orgtitle+content+allcontent 本身。
所以,當我們需要對標題檢索的時候可以直接用title作爲檢索條件,如果對多個域進行檢索,比如我希望title+content+orgtitle這三個字段中只要有一個字段中含有某關鍵詞,那麼就可以用multivalued,配置一下多值即可。
此外,除了可以多值檢索,它還可以設置權重。 參考https://blog.csdn.net/u010248330/article/details/72961551。
關於solr多字段搜索,排序打分規則,可以參考https://www.iteye.com/blog/adminjun-2258480。這兩篇都很詳細。這裏也就不贅述了。
四、dynamicField 動態域
業務場景:並不是我們業務的所有字段都需要在schema.xml、managed-schema指定成固定的字段。
<field name="name" type="string" indexed="true" stored="true"/>、
<field name="sex" type="string" indexed="true" stored="true"/>
這些都是固定的。
例如我現在有一個新業務,大概有5個字段,需要拼接在原來的core裏面,那麼dynamicField就發揮了它的用武之地了。
直接上代碼:
schema.xml、managed-schema文件中的配置如下
<!-- 動態字段 -->
<dynamicField name="solrField_s_*" type="text_general_rev" indexed="true" stored="true"/> 存放String類型
<dynamicField name="solrField_d_*" type="double" indexed="true" stored="true"/> 存放double類型
<dynamicField name="solrField_l_*" type="long" indexed="true" stored="true"/> 存放long類型
java代碼:
// 得到請求
SolrClient sc = getSolrClient();
// 拼裝文本
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", 1);
doc.addField("solrField_s_1", "1");
doc.addField("solrField_s_2", "2");
doc.addField("solrField_d_1", "2.0");
doc.addField("solrField_l_1", "1239012320");
sc.add(doc);
sc.commit();
查詢結果:
{
"responseHeader":{
"status":0,
"QTime":135,
"params":{
"q":"*:*",
"indent":"on",
"wt":"json",
"_":"1510043041895"}},
"response":{"numFound":1,"start":0,"docs":[
{
"id":1,
"solrField_s_1":"1",
"keywords":["1",
"2",
"2.0",
"1239012320"],
"solrField_s_2":"2",
"solrField_d_1":2.0,
"solrField_l_1":1239012320,
"_version_":1583395999953453056}]
}}
通過結果可以看出,我的schema.xml裏面根本就沒配置solrField_s_1,solrField_s_2,solrField_d_1,solrField_l_1這些字段,但是卻能把數據放進去,既然放進去了,那麼肯定也就可以根據對應的字段進行查詢。
不過這裏說一下,動態域用是好用,但是這種東西必然會增加你的維護成本,所以看着用吧。
五、solr的配置IK分詞器
這個我在後面的文章會有詳細的介紹其原理及其使用,先佔一個坑。
六、<uniqueKey>id</uniqueKey>
來判斷數據的唯一性。類似於數據庫的id。
如果id在索引中已經存在,則更新索引。否則插入索引。刪除索引也是按照這個去判斷,下文會講。
七、控制檯
reload:單機環境下,修改完配置文件後,可以不重啓服務,直接點擊reload會重新加載配置文件。
optimize :optimize有點像硬盤上整理磁盤碎片的操作。爲了提高搜索速度,它會將索引重組在一起,然後移除需要被刪除或是更新的文檔。這裏需要注意一下,solr是沒有update的這種操作,只有增加刪除。solr在優化的時候,將需要刪除或者是需要被替換的索引標記爲deleted。然後再創建新的文檔,替換掉需要被替換的。optimize就是執行此操作。因此,再優化的時候,你的索引會先增大,然後再減小。optimize操作會創建一個全新的索引結構,因此,你大概需要預備出二倍於你commit時索引大小的空間,否則會影響你solr的正常服務。
八、java使用solr增刪改查
增加、修改索引。solr會動態根據id。來判斷是更新,還是插入。
刪除索引
這裏需要注意一下,<commit/>語句必不可少。
1.控制檯刪除
刪除core下全部索引:
<delete><query>*:*</query></delete>
<commit/>
刪除指定索引:
<delete><query>id:1</query></delete>
<commit/>
2.Java代碼
solrServer.deleteByQuery("*:*");
第一篇就先到這,如果有哪些地方寫的不對,或者沒有描述準確,歡迎大家留言指正,多謝。