高級搜索插件solis search在umbraco中的使用

很久沒有寫關於umbraco的博客了,這段時間在研究solis search,感受它太強大,好東西是須要分享的,因此寫一篇簡單的使用博客分享給我的umbraco愛好者。javascript

簡介

在瞭解solis search以前,咱們須要簡單的瞭解apache solr, Apache Solr 是一個開源的搜索服務器。Solr 使用 Java 語言開發,主要基於 HTTP 和 Apache Lucene 實現。Lucene是一套用於全文檢索和搜尋的開源程式庫,由Apache軟件基金會支持和提供。Lucene提供了一個簡單卻強大的應用程式接口,可以作全文索引和搜尋。更詳細的介紹請充分利用搜索引擎,這裏就不作詳細介紹了。html

solis search就是基於apache solr開發的一個umbraco的插件。它在作了簡單的配置以後,就能夠檢索到umbraco content裏面的幾乎全部的文字內容,包括上傳的文檔或者選擇的media picker中的文檔(word, pdf, excel 等等)。java

下載安裝

1. 安裝JAVA環境

安裝java環境是爲了運行apache solr server.apache

下載地址:http://www.java.com/zh_CN/,服務器

下載後安裝,安裝以後請配置環境變量,是java命令能夠直接在命令行根目錄運行。如何配置環境變量在這就不介紹了。app

2. 安裝apache solr

下載地址:http://lucene.apache.org/solr/,這裏記住,必定要下載4.5.1版本的,否則使用會出現未知的錯誤。由於solis search是基於version 4.5開發的。ide

請參考官方文檔進行安裝:http://lucene.apache.org/solr/4_5_1/tutorial.htmlui

操做簡要說明:this

  • 解壓壓縮包到電腦的任意位置,建議目錄全是英文的
  • 打開cmd,進入到目錄:solr-4.5.1\example
  • 運行> java -jar start.jar啓動solr server.

3. 安裝 solis search package

下載:https://www.solissearch.com/download/ 搜索引擎

推薦下載Solis Search 1.1.15.218 Umbraco package, 下載以後再umbraco後臺進行安裝

 

安裝過程通常不會出錯,若是出了錯,請下載手動安裝包,根據文檔進行安裝: https://www.solissearch.com/documentation/

安裝以後,找到安裝包裏面的schema.xml和solrconfig.xml而後 複製到solr的文件夾solr-4.5.1\example\solr\collection1\conf\下面,這一步很重要,而後重啓solr server: java -jar start.jar

 

接着就是rebuild index:

固然在rebuild index以前要根據具體的須要修改配置文件。

在這裏,我將個人配置貼出來,而且作簡單的介紹,

 1 <?xml version="1.0"?>
 2 <SolisSearch>
 3   <SolrServer address="http://localhost:8983/solr" username="" licenseKey="" />
 4   <SearchSettings defaultField="text" enableLanguageSupport="true" enabledLanguages="en" highlight="true" highlightFields="text" fragmenter="regex" fragsize="300" defaultOperator="AND" />
 5   <Languages>
 6     <Language name="en" rootNode="1064" />
 7   </Languages>
 8   <DocTypes>
 9     <DocType name="default" addPageNameToContent="true">
10       <Properties>
11         <Property name="p1" property="Name" type="text" content="true" />
12         <Property name="r1" property="relatedLinks" type="relatedLinks" parser="SolisSearch.Parsers.RelatedLinksParser,SolisSearch" />
13       </Properties>
14     </DocType>
15     <DocType name="umbHomePage">
16       <Properties>
17         <Property name="p1" property="mainHeading" type="text" content="true" />
18         <Property name="p2" property="mainContent" type="text" content="true" striphtml="true"/>
19       </Properties>
20     </DocType>
21     <DocType name="newsGroup" addPageNameToContent="true">
22       <Properties>
23         <Property name="p1" property="Name" type="text" content="true" />
24       </Properties>
25     </DocType>
26     <DocType name="newsItem" addPageNameToContent="true">
27       <Properties>
28         <Property name="p1" property="title" type="text" content="true" />
29         <Property name="p2" property="content" type="text" content="true" striphtml="true"/>
30         <Property name="p3" property="downloadFile" type="relatedLinks" parser="SolisSearch.Parsers.RelatedLinksParser,SolisSearch" />
31         <Property name="p4" property="uploadDoc" type="relatedLinks" parser="SolisSearch.Parsers.RelatedLinksParser,SolisSearch" />
32       </Properties>
33     </DocType>
34   </DocTypes>
35   <Facets>
36     <Facet type="value" field="doctypes" mincount="0" sort="false" />
37     <Facet type="range" field="last_modified" mincount="1">
38       <Ranges>
39         <FacetRange name="date3" dynamic="thisday" dataType="date" />
40         <FacetRange name="date4" dynamic="thisweek" dataType="date" />
41         <FacetRange name="date5" dynamic="thismonth" dataType="date" />
42         <FacetRange name="date6" dynamic="thisyear" dataType="date" />
43         <FacetRange name="date7" dynamic="last" gap="20" dataType="date" />
44       </Ranges>
45     </Facet>
46   </Facets>
47 </SolisSearch>
View Code

 

SolrServer:配置solr server的 地址,用戶名以及license key.

SearchSettings: 配置當前search的環境,支持的語言,連接操做符,是否高亮等等

DocTypes:這個是重點,用來配置能夠搜索出來的content字段

1 <DocType name="newsItem" addPageNameToContent="true">
2       <Properties>
3         <Property name="p1" property="title" type="text" content="true" />
4         <Property name="p2" property="content" type="text" content="true" striphtml="true"/>
5         <Property name="p3" property="downloadFile" type="relatedLinks" parser="SolisSearch.Parsers.RelatedLinksParser,SolisSearch" />
6         <Property name="p4" property="uploadDoc" type="relatedLinks" parser="SolisSearch.Parsers.RelatedLinksParser,SolisSearch" />
7       </Properties>
8 </DocType>

 

name="newsItem": 將名爲newsItem的document type添加到可搜索列表;

addPageNameToContent="true": 表示該document type的name是可搜索的;

Properties: 指定該document type中哪些property是能夠被搜索的;

Property: name - 標示符, property - 屬性名, type - 搜索的類型, content - 搜索的是內容值

type="relatedLinks": 表示使用solis search的方法去搜索,通常用來搜索word文檔,pdf文檔中的內容, 須要添加 parser="SolisSearch.Parsers.RelatedLinksParser,SolisSearch".

 

這裏的p3和p4表示添加了media picker類型以及upload的類型的屬性是能夠搜索的。

 

搜索view代碼:

  1 @using System.Activities.Statements
  2 @using System.Globalization
  3 @using SolisSearch.Helpers
  4 @using SolisSearch.Repositories
  5 @inherits Umbraco.Web.Macros.PartialViewMacroPage
  6 
  7 @{
  8     Layout = "../Master.cshtml";
  9 }
 10 
 11 
 12 <h1>@ViewBag.Title</h1>
 13 <h3>@ViewData["content"]</h3>
 14 
 15 @{
 16     var query = HttpUtility.UrlDecode(Request.QueryString["q"]);
 17     var fq = new List<string>();
 18 
 19 
 20     <script type="text/javascript">
 21         $(document).ready(function () {
 22 
 23             $("#txtSearch").keydown(function (e) {
 24                 if (e.which == "13") {
 25                     $("#searchform").submit();
 26                 }
 27             });
 28 
 29             $(".facetlink").click(function () {
 30                 var filter = $(this).attr("data-filter");
 31                 $("#filters").append("<input name='fq' type='hidden' value='" + filter + "¤' >");
 32                 $("#searchform").submit();
 33 
 34             });
 35 
 36             $("#filters").on("click", "a", function () {
 37                 $(this).prev("input").remove();
 38                 $("#searchform").submit();
 39             });
 40         });
 41     </script>
 42 
 43     <div class="searchform">
 44         <form id="searchform" method="GET">
 45             <input id="txtSearch" autocomplete="off" type="search" name="q" value="@query" />
 46             <button type="submit">Search</button>
 47 
 48             @if (!String.IsNullOrEmpty(Request["fq"]))
 49             {
 50                 fq.AddRange(Request["fq"].TrimEnd(Convert.ToChar("¤")).Split(new[] { "¤," }, StringSplitOptions.RemoveEmptyEntries));
 51             }
 52 
 53             <div id="filters">
 54                 @{
 55                     if (fq.Any())
 56                     {
 57                         <h6>Active filters <span>(Click to remove)</span></h6>
 58                         foreach (var field in fq)
 59                         {
 60                             <input name="fq" type="hidden" value="@string.Format("{0", field)" />
 61                             <a href="#">@Html.Raw(GetFriendlyCategoryName(RangeFormatHelper.FormatRange(field)))&nbsp;<i class="fa fa-times"></i></a>
 62                         }
 63 
 64                     }
 65                 }
 66 
 67             </div>
 68         </form>
 69     </div>
 70 
 71 
 72     if (!String.IsNullOrEmpty(query) || fq.Any())
 73     {
 74         var languageName = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
 75 
 76         var searchRepo = new SearchRepository();
 77         var searchResultItems = searchRepo.SearchIndex(query, fq.ToArray(), 1, 0, null);
 78 
 79         if (searchResultItems.SpellChecking.Any())
 80         {
 81             <div class="spellchecking">
 82                 <h4>Did you mean</h4>
 83                 @foreach (var spellitem in searchResultItems.SpellChecking)
 84                 {
 85 
 86                     foreach (var suggestion in spellitem.Suggestions)
 87                     {
 88                         <p><a href="?q=@suggestion">@suggestion</a></p>
 89                     }
 90 
 91                 }
 92             </div>
 93         }
 94 
 95         <div class="facets">
 96             <div>
 97                 @if (searchResultItems.FacetFields.Any())
 98                 {
 99                     var doctypesFacets = searchResultItems.FacetFields["doctypes"];
100                     <h4>Category</h4>
101                     <ul>
102                         @{
103                     foreach (var keyValuePair in doctypesFacets)
104                     {
105                         var friendlyname = GetFriendlyCategoryName(keyValuePair.Key);
106                         if (String.IsNullOrEmpty(friendlyname))
107                         {
108                             continue;
109                         }
110 
111                         <li>
112                             <a class="facetlink" data-filter="@Html.Raw(string.Format("{0}:{1}", "doctypes", keyValuePair.Key))" href="javascript:void(0);">
113                                 @Html.Raw(friendlyname + " (" + keyValuePair.Value + ")")
114                             </a>
115                         </li>
116                     }
117                         }
118 
119                     </ul>
120 
121 
122                 }
123             </div>
124             <div>
125                 @if (searchResultItems.FacetQueries.Any())
126                 {
127                     <h4>Date modified</h4>
128                     <ul>
129                         @foreach (var facetqueries in searchResultItems.FacetQueries)
130                         {
131                             <li>
132                                 <a class="facetlink" data-filter="@facetqueries.Key" data-value="@facetqueries.Key" href="javascript:void(0);">
133                                     @Html.Raw(RangeFormatHelper.FormatRange(facetqueries.Key) + " (" + facetqueries.Value + ")")
134                                 </a>
135                             </li>
136                         }
137                     </ul>
138                 }
139             </div>
140 
141         </div>
142 
143         if (searchResultItems.Any())
144         {
145             <div class="searchResults">
146                 <p>@string.Format("Total of {0} items found", searchResultItems.NumFound)</p>
147                 <ol>
148                     @foreach (var searchitem in searchResultItems)
149                     {
150                         <li>
151                             <h4><a href="@Html.Raw(searchitem.LinkUrl ?? searchitem.ResourceName)">@Html.Raw(searchitem.Name ?? searchitem.DocumentTitle.FirstOrDefault() ?? Path.GetFileNameWithoutExtension(searchitem.ResourceName))</a></h4>
152                             @{
153                                 var highlightedSnippets = searchResultItems.Highlights[searchitem.Id];
154                                 if (highlightedSnippets != null && highlightedSnippets.Any())
155                                 {
156                                     foreach (var highlightItem in highlightedSnippets)
157                                     {
158                                         @Html.Raw(string.Join(" ", highlightItem.Value))
159                                     }
160                                 }
161                                 else
162                                 {
163                                     var contentString = string.Join(" ", searchitem.Content);
164                                     @Html.Raw(contentString.Substring(0, Math.Min(contentString.Length, 175)))
165                                 }
166                             }
167                         </li>
168                     }
169                 </ol>
170             </div>
171 
172         }
173         else
174         {
175             <p style="clear: both;">No search results</p>
176         }
177     }
178 }
179 
180 @functions
181 {
182 
183     private string GetFriendlyCategoryName(string doctype)
184     {
185         if (doctype.Contains("/")) return doctype;
186         switch (doctype)
187         {
188             case "newsItem":
189                 return "News Item";
190             case "umbHomePage":
191                 return "Article";
192             default:
193                 return "Others";
194 
195         }
196     }
197 
198 }
View Code

 

 

作了如上操做後,就能夠開始使用solis search進行操做了。

 

 

有錯誤的地方,歡迎指出。

 

參考:

https://www.solissearch.com/

http://baike.baidu.com/view/5649738.htm?fr=aladdin

http://baike.baidu.com/view/371811.htm

 

尊重原創,轉載請說明出處!

相關文章
相關標籤/搜索