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

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

  • 相关阅读:
    周报说明8-4
    周报7-28
    日志-maven-c监控 周报7-21
    证明创建runnable实例和普通类时间一样长, 其实吧
    UE4开始之路
    js简单框架设计
    json中key为数字会自动排序问题
    u3动画
    工厂模式
    单例模式
  • 原文地址:https://www.cnblogs.com/huangbx/p/4162160.html
Copyright © 2011-2022 走看看