zoukankan      html  css  js  c++  java
  • 高级搜索插件solis search在umbraco中的使用

    好久没有写关于umbraco的博客了,这段时间在研究solis search,感觉它太强大,好东西是需要分享的,所以写一篇简单的使用博客分享给个人umbraco爱好者。

    简介

    在了解solis search之前,我们需要简单的了解apache solr, Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。更详细的介绍请充分利用搜索引擎,这里就不做详细介绍了。

    solis search就是基于apache solr开发的一个umbraco的插件。它在做了简单的配置之后,就可以检索到umbraco content里面的几乎所有的文字内容,包括上传的文档或者选择的media picker中的文档(word, pdf, excel 等等)。

    下载安装

    1. 安装JAVA环境

    安装java环境是为了运行apache solr server.

    下载地址:http://www.java.com/zh_CN/,

    下载后安装,安装之后请配置环境变量,是java命令可以直接在命令行根目录运行。如何配置环境变量在这就不介绍了。

    2. 安装apache solr

    下载地址:http://lucene.apache.org/solr/,这里记住,一定要下载4.5.1版本的,不然使用会出现未知的错误。因为solis search是基于version 4.5开发的。

    请参考官方文档进行安装:http://lucene.apache.org/solr/4_5_1/tutorial.html

    操作简要说明:

    • 解压压缩包到电脑的任意位置,建议目录全是英文的
    • 打开cmd,进入到目录:solr-4.5.1example
    • 运行> 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.1examplesolrcollection1conf下面,这一步很重要,然后重启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

    尊重原创,转载请说明出处!

  • 相关阅读:
    Android开发之Sqlite的使用
    ZOJ 3607 Lazier Salesgirl
    ZOJ 3769 Diablo III
    ZOJ 2856 Happy Life
    Ural 1119 Metro
    Ural 1146 Maximum Sum
    HDU 1003 Max Sum
    HDU 1160 FatMouse's Speed
    Ural 1073 Square Country
    Ural 1260 Nudnik Photographer
  • 原文地址:https://www.cnblogs.com/huangbx/p/4162160.html
Copyright © 2011-2022 走看看