前言

首先,关于Lucene.Net 的文章已经很多了。我这次决定写出来只是为了练练手,虽然在别人看来没什么用,但是自己确实是手动实践了一把。我个人觉得还是有意义的。爱折腾、敢于实践、才能有所收获,才能发现问题。不要怕自己写的东西有问题,有问题才更好呢,可以让更多的人看见,提意见的当然是好,鄙视的……我也接受,给自己 动力去思考。

想让自己时刻保持着这种程序员-->代码心态、人都是带有惰性的,一旦玩起来 呵呵...

效果显示

进入主题

相信大家对于LuceneNet 并不陌生了,园子里面的文章很多。

参考文章:

http://www.cnblogs.com/birdshover/category/152283.html

http://www.cnblogs.com/psforever/archive/2011/10/06/2200019.html

界面是一个在线工具自己手动构的,可以随意的设计自己想要的界面。但是引用的css居然不是Bootstrap的css,这点得注意。

css样式引用地址:http://www.bootcss.com/p/layoutit/css/bootstrap-combined.min.css

            http://www.bootcss.com/p/layoutit/css/layoutit.css

在线工具地址:http://www.bootcss.com/p/layoutit/

数据库大概8w条记录,每次最多取出1W条查询结果。正常人也不会看完这么多的。

核心代码

方法

        /// <summary>
/// 获得搜索列表
/// </summary>
/// <param name="keyword">关键字</param>
/// <param name="pageSize"></param>
/// <param name="currentPage">当前页码</param>
/// <param name="count"></param>
/// <param name="pageCount"></param>
/// <param name="isLike">是否开启模糊查询</param>
/// <returns></returns>
public static List<StoreInfo> GetSearchList(string keyword, int pageSize, int currentPage, out int count, out int pageCount, bool isLike = false)
{
string keywords = keyword; //获取用户输入关键字,以备设置高亮显示
string strIndexPath = INDEX_STORE_PATH;
List<StoreInfo> storeList = new List<StoreInfo>();
StoreInfo modelstore;
pageCount = ;
count = ; IndexSearcher search = null;
try
{
search = new IndexSearcher(FSDirectory.Open(new System.IO.DirectoryInfo(strIndexPath)), true);
}
catch (Exception)
{
return null;
} keyword = GetKeyWordsSplitBySpace(keyword, new PanGuTokenizer()); QueryParser titleQueryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "body", new PanGuAnalyzer(true));
Query titleQuery = titleQueryParser.Parse(keyword); Query PrefixQuery_title = null;
Query PrefixQuery_body = null;
Query FuzzyQuery_Title = null;
Query FuzzyQuery_body = null;
Query WildcardQuery_title = null;
Query WildcardQuery_body = null; if (isLike)
{
//以什么开头,输入“ja”就可以搜到包含java和javascript两项结果了
PrefixQuery_title = new PrefixQuery(new Term("title", keywords));
PrefixQuery_body = new PrefixQuery(new Term("body", keywords));
//直接模糊匹配,假设你想搜索跟‘wuzza’相似的词语,你可能得到‘fuzzy’和‘wuzzy’。
FuzzyQuery_Title = new FuzzyQuery(new Term("title", keywords));
FuzzyQuery_body = new FuzzyQuery(new Term("body", keywords));
//通配符搜索
WildcardQuery_title = new WildcardQuery(new Term("title", keywords));
WildcardQuery_body = new WildcardQuery(new Term("body", keywords));
} //MultiFieldQueryParser
BooleanQuery bq = new BooleanQuery(); bq.Add(titleQuery, BooleanClause.Occur.SHOULD);//表示条件关系为“or”,BooleanClause.Occur.MUST表示“and”,BooleanClause.Occur.MUST_NOT表示“not” if (isLike)
{
bq.Add(PrefixQuery_title, BooleanClause.Occur.SHOULD);
bq.Add(PrefixQuery_body, BooleanClause.Occur.SHOULD);
bq.Add(FuzzyQuery_Title, BooleanClause.Occur.SHOULD);
bq.Add(FuzzyQuery_body, BooleanClause.Occur.SHOULD);
bq.Add(WildcardQuery_title, BooleanClause.Occur.SHOULD);
bq.Add(WildcardQuery_body, BooleanClause.Occur.SHOULD);
} //创建一个结果收集器(收集结果最大数为1000页)
TopScoreDocCollector collector = TopScoreDocCollector.create(pageSize * , true);
search.Search(bq, null, collector);
TopDocs topDoc = collector.TopDocs(, collector.GetTotalHits()); //搜索结果总数超出指定收集器大小,则摈弃
if (topDoc.totalHits > pageSize * )
count = pageSize * ;
else
count = topDoc.totalHits; int i = (currentPage - ) * pageSize; #region
Lucene.Net.Documents.Document docs;
PanGu.HighLight.Highlighter highlighter;
PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter; while (i < count && storeList.Count < pageSize)
{
modelstore = new StoreInfo(); docs = search.Doc(topDoc.scoreDocs[i].doc);
try
{
string strTitle = docs.Get("title");
string strContent = docs.Get("body");
modelstore.Store_ID = Convert.ToInt32(docs.Get("id")); //高亮显示设置
simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<span style=\"color:red;\">", "</span>");
highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment());
highlighter.FragmentSize = ; //string GetBestFragment(keywords,content)方法会按照SimpleHTMLFormatter构造的格式对content中关键字进行高亮显示
//但如果content中不包含keywords则会返回空值,故需要按照如下进行判断
modelstore.Description = highlighter.GetBestFragment(keywords, strContent);
if (string.IsNullOrEmpty(modelstore.Description))
{
modelstore.Description = strContent;
}
modelstore.Store_Name = highlighter.GetBestFragment(keywords, strTitle);
if (string.IsNullOrEmpty(modelstore.Store_Name))
{
modelstore.Store_Name = strTitle;
}
}
catch (Exception e)
{
continue;
}
finally
{
storeList.Add(modelstore);
i++;
}
}
#endregion search.Close();
pageCount = Convert.ToInt32(Math.Ceiling((double)collector.GetTotalHits() / pageSize)); return storeList;
}

控制器

        public ActionResult Index(string id = "", string kw = "", string isLike = "", int pageIndex = )
{
string strKeyWorld = HttpDecode(id.Length == ? kw : id);
int pageSize = ;
int intCount = ;
int intPageCount = ;
bool _boolisLike = isLike == "" ? true : false;
List<StoreInfo> StoreInfoList = null;
Stopwatch watch = new Stopwatch();
watch.Start();//调用方法开始计时 if (strKeyWorld.Length > )
{
StoreInfoList = LuceneNetUtils.GetSearchList(strKeyWorld, pageSize, pageIndex, out intCount, out intPageCount, _boolisLike);
}
watch.Stop();//调用方法计时结束
double time = watch.Elapsed.TotalSeconds;//总共花费的时间 ViewBag.time = time;
ViewBag.kw = strKeyWorld;
ViewBag.count = intCount;
ViewBag.pageIndex = pageIndex;
ViewBag.pageSize = pageSize;
ViewBag.intPageCount = intPageCount;
ViewBag._boolisLike = _boolisLike; return View(StoreInfoList);
}

View视图

注意:ShowPageBarMvc是个页码条,在页面当中用的时候一定要引用所在命名空间,或者添加webConfig

@using System.Web.Optimization;
@using LX.EFOPT.Web.Main.CommonUtils;
@using PagedList;
@using PagedList.Mvc;
@model List<LX.EFOPT.Web.Main.Models.StoreInfo>
@{
Layout = "/Views/Shared/_LayoutLucene.cshtml";
} <script src="~/Js/jquery.ds.js"></script>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<form class="form-search" action="/LuceneNet/index/" onsubmit="return _search.checkInput();">
<input class="input-medium search-query" id="inputKw" name="kw" value="@ViewBag.kw" type="text" />
<button id="btn_search" type="submit" class="btn">查找</button>&nbsp;
<input type="checkbox" @(ViewBag._boolisLike ? "checked=checked":"") name="isLike" id="isLike" value="" /><label for="isLike">是否开启模糊查询</label>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button id="btn_createIndex1" type="button" class="btn">创建索引-方式1</button>
<button id="btn_createIndex2" type="button" class="btn">创建索引-方式2</button>
</form>
<div id="ajaxData" style="width:80%">
@{
if (Model != null)
{
<div style="margin-top:20px;"><p>获得约 @ViewBag.count 条结果,用时 @ViewBag.time 秒</p></div>
foreach (var item in Model)
{
<div style="margin-top:20px;">
<h4>@item.Store_ID @Html.Raw(item.Store_Name)</h4>
<p>@Html.Raw(item.Description)</p>
<p><a class="btn" href="javascript:;">查看更多 »</a></p>
</div>
} int pageIndex = ViewBag.pageIndex;
int pageSize = ViewBag.pageSize;
int intCount = ViewBag.count;
string kw = ViewBag.kw;
string isLike = ViewBag._boolisLike ? "":"";
@Html.ShowPageBarMvc("/LuceneNet/Index", pageIndex, pageSize, intCount, "kw=" + kw + "&isLike=" + isLike)
}
else
{
<div style="margin-top:20px;"><h4>没有找到你想要的数据</h4><p>可以更改关键字试试</p></div>
}
}
</div>
</div>
</div>
</div>
@Scripts.Render("/LuceneNet/js/Search.js")

Js创建索引

/// <reference path="../../Js/jquery-1.7.1.min.js" />
/// <reference path="../../Js/jquery.ds.js" /> function LuceneNet() {
this.$_inputKw = $("#inputKw");
this.$_btn_search = $("#btn_search");
this.$_btn_createIndex1 = $("#btn_createIndex1");
this.$_btn_createIndex2 = $("#btn_createIndex2");
} LuceneNet.prototype.init = function () {
var _self = this; _self.$_btn_createIndex1.on("click", function () {
_self.createIndex(1);
});
_self.$_btn_createIndex2.on("click", function () {
_self.createIndex(2);
});
}; LuceneNet.prototype.checkInput = function () {
_self = this; if (!_self.$_inputKw.val().length) {
return false;
}
} LuceneNet.prototype.createIndex = function (_type) {
_self = this;
$.ds.tips.open("loading", "请稍后..");
$.ajax({
url: "/LuceneNet/CreateIndex",
type: "get",
dataType: "json",
data: { type: _type },
contentType: "application/x-www-form-urlencoded; charset=utf-8",
success: function (data) {
$.ds.tips.close();
}
});
} LuceneNet.prototype.Search = function () { _self = this; $.ajax({
url: "/",
type: "get",
dataType: "json",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: { kw: decodeURI(_self.$_inputKw.val()) },
success: function (data) { }
});
}; var _search = new LuceneNet();
_search.init();

下一篇将继续折腾添加索引和删除索引,和数据库保持同步。

源代码只是我在公司测试的一个项目,比较杂,没有办法全部提供下载。但是我会把代码上传到git或者是网盘

谢谢。

原文地址:http://www.cnblogs.com/lxsweat/p/4386420.html

瞎折腾之 Lucene.Net + MVC 搜索功能(上)的更多相关文章

  1. 如何使用 Lucene 做网站高亮搜索功能?

    现在基本上所有网站都支持搜索功能,现在搜索的工具有很多,比如Solr.Elasticsearch,它们都是基于 Lucene 实现的,各有各的使用场景.Lucene 比较灵活,中小型项目中使用的比较多 ...

  2. 【Lucene】Apache Lucene全文检索引擎架构之搜索功能3

    上一节主要总结了一下Lucene是如何构建索引的,这一节简单总结一下Lucene中的搜索功能.主要分为几个部分,对特定项的搜索:查询表达式QueryParser的使用:指定数字范围内搜索:指定字符串开 ...

  3. 如何在Web前端实现CAD图文字全文搜索功能之技术分享

    现状 在CAD看图过程中我们经常会需要用到查找文字的功能,在AutoCAD软件查找一个文字时,可以通过打开左下角输入命令find,输入查找的文字,然后设置查找范围,就可以搜索到需要查询的文字.但在We ...

  4. 瞎折腾之 NHibernate ORM框架的接触(MVC + Repository源码)(一)

    在这炮火连天.技术更新迅猛的年代,不接触了解.甚至会用2~3种框架都不好意思说自己有多少年工作经验.况且出去面试也会有点吹牛的底子嘛. 这次折腾了NHibernate.其实这些ORM框架封装好了都是给 ...

  5. Lucene 搜索功能

    搜索过程 图解: 主要 API: IndexSearcher:    //所有搜索都通过 IndexSearcher 进行,他们将调用该类中重载的 search() 方法 Query:         ...

  6. 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能

    package com.jadyer.lucene; import java.io.File; import java.io.IOException; import java.text.SimpleD ...

  7. Lucene5.5.4入门以及基于Lucene实现博客搜索功能

    前言 一直以来个人博客的搜索功能很蹩脚,只是自己简单用数据库的like %keyword%来实现的,所以导致经常搜不到想要找的内容,而且高亮显示.摘要截取等也不好实现,所以决定采用Lucene改写博客 ...

  8. 011.Adding Search to an ASP.NET Core MVC app --【给程序添加搜索功能】

    Adding Search to an ASP.NET Core MVC app 给程序添加搜索功能 2017-3-7 7 分钟阅读时长 作者 本文内容 1.Adding Search by genr ...

  9. asp.net mvc 简单搜索功能

    View中代码: <input type="text" class="searchText" id="searchText"/> ...

随机推荐

  1. 树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count

    这是树链剖分的入门题,也是我学树链剖分的第一题. 树链剖分:就是把树中和线段树联系起来,求(u,v)路径中权值的最大值和其路径的权值和. 入门blog:http://blog.sina.com.cn/ ...

  2. 提高Asp.Net应用程序性能的十大方法(译感)

    译完了提高Asp.Net应用程序的十大方法这篇文章,仔细想其中提到的每一条,在这里结合我的项目来谈谈.第一条:返回多个结果集因为我的项目中所有对数据库的访问的sql语句都是通过调用存储过程实现的,所以 ...

  3. ubuntu安装后没有root密码

    新安装的ubuntu没有设置root密码,也就不能登录到root账户下.要想设置root密码需要在当前账户下输入sudo passwd,然后输入当前用户的密码,然后输入两次root的新密码,即可完成r ...

  4. Unity3D判断鼠标向右或向左滑动,响应不同的事件

    private var first = Vector2.zero; private var second = Vector2.zero; function Update () { } function ...

  5. 利用Openvswitch实现不同物理机中的Docker容器互连

    1. 测试环境 75机(10.11.150.75):Red Hat Enterprise Linux Server 7.0,无外网访问权限,已安装Docker Server 74机(10.11.150 ...

  6. 请教DotNetBar控件中的CalendarView控件如何拖动当前的时间轴

    本人想拖动那个当前的时间轴或者让时间轴变动,因为那个时间轴默认的是当前时间.(就是那个黄色的线)

  7. FastDfs点滴

    1.centos安装后提示找不到libevent动态库 根据系统是64位版本还是32位版本,若是64位版本则默认回到 /usr/lib64 目录下查找,而对于32位则到 /usr/lib 目录下查找. ...

  8. POJ 2533 Longest Ordered Subsequence

    题目描述:LIS(Longest Increasing Subsequence)模板题 分析:O(n^2)的方法 状态表示:d[i]表示以i结尾的最长上升子序列长度 转移方程:d[i]=max{ 1, ...

  9. sizeof学习理解

    以下内容转自: http://www.cnblogs.com/ComputerG/archive/2012/02/02/2335611.html 博问 闪存 首页 新随笔 联系 管理 随笔- 72  ...

  10. linux下ssh/scp无密钥登陆方法

    一.双方机器都是root用户登陆方法 A为本地主机(即用于控制其他主机的机器) ;B为远程主机(即被控制的机器Server), 假如ip为192.168.60.110;A和B的系统都是Linux 在A ...