全文检索引擎

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fanbin168/article/details/79947920

简介

参考文章:https://www.cnblogs.com/eggTwo/p/4425269.html

现在主流网站,APP都有“站内搜索”的功能:优酷,爱奇艺,链家,携程......等等。如果用SQL做站内搜索的话,

例如:select * from t where Title like '%西游记%'  这种方式的缺点就是:容易全表扫描,性能不好,对数据库的压力大


现在我们一种搜索引擎服务器可以解决我们的问题

全文检索引擎开发包有 Lucene ,Solr ,Elastic Search等

其中Lucene是Java编写的全文检索引擎引擎底层开发包,它也有.Net移植版本,叫Lucene.Net 。基于Lucene开发难度比较大。因此有人开发出了基于Lucene的搜索引擎服务器,Solr ,Elastic Search等

环境搭建

现在我们要讲的就是Elasticc Search搜索引擎服务器

Elasticc Search搜索引擎服务器简称ES ,它是使用Java开发的,因此运行的时候要配置Java的运行环境。这些搜索引擎服务器都是“客户端SDK+服务器”的这种使用方法

第一步:Elasticc Search安装

1> 下载安装Java运行环境JDK1.8 


2> Java的环境变量配置

win7系统: 首先右击【计算机】进入【属性】然后选择其中的【高级系统设置】点击进入【高级】中的【环境变量】,进入环境变量编辑界面。


点击新建 

变量名(N)叫 JAVA_HOME

变量值 就是你Java JDB1.8的安装目录

点击确定,那么Java的环境变量配置就配置好了

第二步:下载安装Elasticc Search

去官网地址下载 Elasticc Search:https://www.elastic.co/cn/downloads/elasticsearch

我下载的是最近版本:6.2.3 下载后,解压,我解压到了D盘 (注意如果是6.2.3版本测试发现数据保存失败,我后来更换成了5.2.0版本,根据保存成功)


打开cmd ,cd到 D:\elasticsearch-6.2.3文件夹下的bin目录,然后执行 elasticcsearch.bat


回车执行

【如果执行过程中报  Error occurred during initialization of VM

Could not reserve enough space for object heap 错误 】那么我们只要去D:\elasticsearch-6.2.3文件夹下的config文件夹下找到jvm.options 文件,将服务占用的堆栈空间改小点就行了:改法如下图


执行完毕后我们可以在本机浏览器中输入127.0.0.1:9200来检查 elasticsearch服务是否运行成功

【注意:执行完毕后这个cmd窗口不要关闭,关闭后服务就停止了】

看到以下情况则表示成功。(如果用IE浏览器打开的话可能弹出一个让你保存的Json文件,如果Json文件内容是如下的话也表示服务运行成功)


第三步:使用

以上服务器都搭建好了,下面就来演示怎么通过代码来连接这个 Elasticc Search服务器

SDK有很多中驱动,如: ElasticSearch.Net ,NEST , PlainElastic.Net 等都可以使用,这里就使用PlainElastic.Net

1> 在项目中 通过Nuget安装PlainElastic.Net


控制器中调用:

存数据

using PlainElastic.Net;
using PlainElastic.Net.Serialization;
using System;
using System.Web.Mvc;

namespace ElasticSearch.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Person p1 = new Person();
            p1.Id = 100698;
            p1.Age = 18;
            p1.Name = "林黛玉ere";
            p1.Describe = "ee林黛玉与贾宝玉青春年少,有共同的理想志趣和叛逆精神而慢慢发展成爱情。绛珠还泪的神话赋予了林黛玉迷人的诗人气质,为宝黛爱情注入了带有奇幻元素的罗曼蒂克色彩,同时又定下了悲剧基调。";
            try
            {
                ElasticConnection client = new ElasticConnection("127.0.0.1", 9200);
                var serializer = new JsonNetSerializer();
                //第一个参数相当于“数据库”,第二个参数相当于“表”,第三个参数相当于“主键”
                IndexCommand cmd = new IndexCommand("yzk", "persons", p1.Id.ToString());
                //Put()第二个参数是要插入的数据
                OperationResult result = client.Put(cmd, serializer.Serialize(p1));
                var indexResult = serializer.ToIndexResult(result.Result);
                if (indexResult.created)
                {
                    return Content("创建成功");
                }
                else
                {
                    return Content("没创建" + indexResult.error);
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                throw ex;
            }

            //如何知道插入成功?看 indexResult 返回值。如果 id 已经存在,则不再插入,如果想覆盖 update 的话,就要先删再插。
        }
    }
    public class Person
    {
        public int Id { get; set; }
        public int Age { get; set; }
        public string Name { get; set; }
        public string Describe { get; set; }
    }
}

读取数据

/// <summary>
/// 读取数据(查询DbIndexName数据库中TbIndexType表的Field字段中包含Context值的数据)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="DbIndexName">存的时候设置的值(相当于数据库)</param>
/// <param name="TbIndexType">存的时候设置的值(相当于表)</param>
/// <param name="Field">表的字段</param>
/// <param name="Context">字段的内容</param>
/// <returns></returns>
public SearchResult<T> Search<T>(string DbIndexName, string TbIndexType, string Field, string Context)
{
    ElasticConnection client = new ElasticConnection("127.0.0.1", 9200);
    SearchCommand cmd = new SearchCommand(DbIndexName, TbIndexType);
    var query = new QueryBuilder<T>();

    query = query.Query(r => r.Bool(
        m => m.Must(t => t.QueryString(t1 => t1.DefaultField(Field).Query(Context)))

        ));
    string querySql = query.Build();
    var result = client.Post(cmd, querySql);
    var serializer = new JsonNetSerializer();
    SearchResult<T> list = serializer.ToSearchResult<T>(result);
    return list;

}

在控制器中对获取到的数据遍历

public class HomeController : Controller
{
    public ActionResult Index()
    {

        //注意:这个数据使用的是延迟加载
        var resultData = Search<Person>("yzk", "persons", "Describe", "贾宝玉的");
        var count = resultData.hits.total;//获取到查询到数据的总条数
        var took = resultData.took; //查询数据花费的毫秒数

        //第一种
        var list = resultData.hits.hits.Select(r => new Person()
        {
            Id = r._source.Id,
            Name = r._source.Name,
            Age = r._source.Age,
            Describe = r._source.Describe

        }).ToList();

        //第二种
        foreach (var item in resultData.Documents)
        {
            var id = item.Id;
            var name = item.Name;
            var age = item.Age;
            var Describe = item.Describe;
        }

        return View(list);
	}
}

删除

(ES没有更新,如果想更新一条数据,就先删除,然后再插入)

/// <summary>
///  删除
/// </summary>
/// <param name="DbIndexName">存的时候设置的值(相当于数据库)</param>
/// <param name="TbIndexType">存的时候设置的值(相当于表)</param>
/// <param name="Id">存的时候设置的值(主键)</param>
/// <returns></returns>
public OperationResult Delete(string DbIndexName, string TbIndexType, string Id)
{
    ElasticConnection client = new ElasticConnection("127.0.0.1", 9200);
    DeleteCommand cmd = new DeleteCommand(DbIndexName, TbIndexType, Id);
    var result = client.Delete(cmd);
    return result;
}



阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页