Elasticsearch.Net使用教程 MVC4图书管理系统(2)

本文实例为大家分享了MVC4图书管理系统的制作教程,供大家参考,具体内容如下

首先项目结构图:

Model层的相关代码如下:
Book.cs代码如下:

public class Book
 {
 [Key]
 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
 public Guid Id { get; set; } 

 [MaxLength(500)] 

 [Display(Name = "标题")]
 public string Title { get; set; } 

 [MaxLength(5000)]
 [Display(Name = "前言")]
 public string Foreword { get; set; } 

 [Display(Name = "总页数")]
 public int Pages { get; set; } 

 [Display(Name = "作者")]
 public string Author { get; set; }
 }
public class AppContext:DbContext
 {
 public AppContext()
 { 

 }
 public DbSet<Book> Books { get; set; }
 } 

ViewModels的相关:

public class SearchViewModel
 {
 public string Query { get; set; } 

 public IEnumerable<IHit<Book>> Results { get; set; } 

 public IDictionary<string, Suggest[]> Suggestions { get; set; } 

 public long Elapsed { get; set; } 

 }

接下来就HomeController.cs和BooksController.cs的代码:

public class HomeController : Controller
 {
 private SearchService _searchService;
 public HomeController()
 {
  _searchService = new SearchService();
 }
 public ActionResult Index()
 { 

  return View();
 } 

 public ActionResult Search(string query, int page = 0, int pageSize = 10)
 { 

  var result = _searchService.Find(query, page, pageSize);
  var suggestion = _searchService.FindPhraseSuggestion(query, 0, 3); 

  var viewModel = new SearchViewModel { Query = query, Results = result.Item1,Elapsed = result.Item2, Suggestions = suggestion }; 

  return View("Index", viewModel);
 } 

 }
public class BooksController : Controller
 {
 private AppContext db = new AppContext(); 

 public ActionResult Index()
 {
  return View(db.Books.ToList());
 } 

 public ActionResult Details(Guid? id)
 {
  if (id == null)
  {
  return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  }
  Book book = db.Books.Find(id);
  if (book == null)
  {
  return HttpNotFound();
  }
  return View(book);
 } 

 public ActionResult Create()
 {
  return View();
 } 

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Create([Bind(Include="Id,Title,Foreword,Pages,Author")] Book book)
 {
  if (ModelState.IsValid)
  {
  book.Id = Guid.NewGuid();
  db.Books.Add(book);
  db.SaveChanges(); 

  //添加书
  Elasticsearch.Elasticsearch.Client.Index<Book>(book); 

  return RedirectToAction("Index");
  } 

  return View(book);
 } 

 public ActionResult Edit(Guid? id)
 {
  if (id == null)
  {
  return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  }
  Book book = db.Books.Find(id);
  if (book == null)
  {
  return HttpNotFound();
  }
  return View(book);
 } 

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Edit([Bind(Include="Id,Title,Foreword,Pages,Author")] Book book)
 {
  if (ModelState.IsValid)
  {
  db.Entry(book).State = EntityState.Modified;
  db.SaveChanges();
  return RedirectToAction("Index");
  }
  return View(book);
 } 

 public ActionResult Delete(Guid? id)
 {
  if (id == null)
  {
  return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  }
  Book book = db.Books.Find(id);
  if (book == null)
  {
  return HttpNotFound();
  }
  return View(book);
 } 

 [HttpPost, ActionName("Delete")]
 [ValidateAntiForgeryToken]
 public ActionResult DeleteConfirmed(Guid id)
 {
  Book book = db.Books.Find(id);
  db.Books.Remove(book);
  db.SaveChanges();
  return RedirectToAction("Index");
 } 

 public JsonResult Reindex()
 {
  foreach (var book in db.Books)
  {
  //Indexing book
  Elasticsearch.Elasticsearch.Client.Index<Book>(book);
  }
  return Json("OK",JsonRequestBehavior.AllowGet);
 } 

 protected override void Dispose(bool disposing)
 {
  if (disposing)
  {
  db.Dispose();
  }
  base.Dispose(disposing);
 }
 }

Elasticsearch辅助类:
首先是Elasticsearch.cs

public class Elasticsearch
 {
 private static ElasticClient _client;
 public static ElasticClient Client
 {
  get
  {
  if (_client == null)
  {
   //连接配置
   var setting = new ConnectionSettings(ElasticsearchConfiguration.Connection,ElasticsearchConfiguration.DefaultIndex);
   _client = new ElasticClient(setting);
  }
  return _client;
  } 

 }
 }

ElasticsearchConfiguration.cs类

public static class ElasticsearchConfiguration
 {
 public static string Host { get { return "http://localhost"; } } 

 public static long Port { get { return 9200; } } 

 public static Uri Connection
 {
  get { return new Uri(string.Format("{0}:{1}", Host, Port)); }
 } 

 public static string DefaultIndex
 {
  get { return "library"; }
 }
 }

SearchService.cs代码:

public class SearchService
 {
 public double MinScore { get {return 0.0005; }} 

 //高亮标记前缀
 public string PreHighlightTag
 {
  get { return @"<strong>"; }
 } 

 //高亮标记后缀
 public string PostHighlightTag
 {
  get { return @"</strong>"; }
 } 

 public Tuple< IEnumerable<IHit<Book>>,long> Find(string query, int page = 0, int pageSize = 10)
 {
  var result = Elasticsearch.Elasticsearch.Client.Search<Book>(s => s
  .From(page * pageSize)
  .Size(pageSize)
  .MinScore(MinScore)
  .Highlight(h => h
   .PreTags(PreHighlightTag)
   .PostTags(PostHighlightTag)
   .OnFields(
   f => f.OnField(b => b.Foreword),
   f => f.OnField(b => b.Title)
   ))
  .Query(q => q.QueryString(qs => qs.Query(query).UseDisMax()))); 

  return new Tuple<IEnumerable<IHit<Book>>, long>(result.Hits,result.ElapsedMilliseconds);
 } 

 //查找短语建议
 public IDictionary<string, Suggest[]> FindPhraseSuggestion(string phrase, int page = 0, int pageSize = 5)
 {
  var result = Elasticsearch.Elasticsearch.Client.Search<Book>(s => s
  .From(page*pageSize)
  .Size(pageSize)
  .SuggestPhrase("did-you-mean", ps => ps
   .Text(phrase)
   .OnField(f => f.Foreword))
  .Query(q => q.MatchAll())); 

  return result.Suggest;
 } 

 public IEnumerable<IHit<Book>> FindAll()
 {
  var result = Elasticsearch.Elasticsearch.Client.Search<Book>(s => s.AllIndices());
  return result.Hits;
 } 

 }

Views视图
Books文件夹下:
Index.cshtml:

@model IEnumerable<Library.Web.Models.Book> 

@{
 ViewBag.Title = "Index";
 Layout = "~/Views/Shared/_Layout.cshtml";
} 

<h2>Index</h2> 

<p>
 @Html.ActionLink("创建新书", "Create")
</p>
<table class="table">
 <tr>
 <th>
  @Html.DisplayNameFor(model => model.Title)
 </th>
 <th>
  @Html.DisplayNameFor(model => model.Foreword)
 </th>
 <th>
  @Html.DisplayNameFor(model => model.Pages)
 </th>
 <th>
  @Html.DisplayNameFor(model => model.Author)
 </th>
 <th></th>
 </tr> 

@foreach (var item in Model) {
 <tr>
 <td>
  @Html.DisplayFor(modelItem => item.Title)
 </td>
 <td>
  @Html.DisplayFor(modelItem => item.Foreword)
 </td>
 <td>
  @Html.DisplayFor(modelItem => item.Pages)
 </td>
 <td>
  @Html.DisplayFor(modelItem => item.Author)
 </td>
 <td>
  @Html.ActionLink("编辑", "Edit", new { id=item.Id }) |
  @Html.ActionLink("详细", "Details", new { id=item.Id }) |
  @Html.ActionLink("删除", "Delete", new { id=item.Id })
 </td>
 </tr>
} 

</table>

Edit.cshtml:

@model Library.Web.Models.Book 

@{
 ViewBag.Title = "Edit";
 Layout = "~/Views/Shared/_Layout.cshtml";
} 

<h2>Edit</h2> 

@using (Html.BeginForm())
{
 @Html.AntiForgeryToken() 

 <div class="form-horizontal">
 <h4>Book</h4>
 <hr />
 @Html.ValidationSummary(true)
 @Html.HiddenFor(model => model.Id) 

 <div class="form-group">
  @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.EditorFor(model => model.Title)
  @Html.ValidationMessageFor(model => model.Title)
  </div>
 </div> 

 <div class="form-group">
  @Html.LabelFor(model => model.Foreword, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.TextAreaFor(model => model.Foreword)
  @Html.ValidationMessageFor(model => model.Foreword)
  </div>
 </div> 

 <div class="form-group">
  @Html.LabelFor(model => model.Pages, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.EditorFor(model => model.Pages)
  @Html.ValidationMessageFor(model => model.Pages)
  </div>
 </div> 

 <div class="form-group">
  @Html.LabelFor(model => model.Author, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.EditorFor(model => model.Author)
  @Html.ValidationMessageFor(model => model.Author)
  </div>
 </div> 

 <div class="form-group">
  <div class="col-md-offset-2 col-md-10">
  <input type="submit" value="Save" class="btn btn-default" />
  </div>
 </div>
 </div>
} 

<div>
 @Html.ActionLink("返回列表", "Index")
</div> 

@section Scripts {
 @Scripts.Render("~/bundles/jqueryval")
}

Details.cshtml:

@model Library.Web.Models.Book 

@{
 ViewBag.Title = "Details";
 Layout = "~/Views/Shared/_Layout.cshtml";
} 

<h2>Details</h2> 

<div>
 <h4>Book</h4>
 <hr />
 <dl class="dl-horizontal">
 <dt>
  @Html.DisplayNameFor(model => model.Title)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Title)
 </dd> 

 <dt>
  @Html.DisplayNameFor(model => model.Foreword)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Foreword)
 </dd> 

 <dt>
  @Html.DisplayNameFor(model => model.Pages)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Pages)
 </dd> 

 <dt>
  @Html.DisplayNameFor(model => model.Author)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Author)
 </dd> 

 </dl>
</div>
<p>
 @Html.ActionLink("编辑", "Edit", new { id = Model.Id }) |
 @Html.ActionLink("返回列表", "Index")
</p>

Delete.cshtml:

@model Library.Web.Models.Book 

@{
 ViewBag.Title = "Delete";
 Layout = "~/Views/Shared/_Layout.cshtml";
} 

<h2>Delete</h2> 

<h3>Are you sure you want to delete this?</h3>
<div>
 <h4>Book</h4>
 <hr />
 <dl class="dl-horizontal">
 <dt>
  @Html.DisplayNameFor(model => model.Title)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Title)
 </dd> 

 <dt>
  @Html.DisplayNameFor(model => model.Foreword)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Foreword)
 </dd> 

 <dt>
  @Html.DisplayNameFor(model => model.Pages)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Pages)
 </dd> 

 <dt>
  @Html.DisplayNameFor(model => model.Author)
 </dt> 

 <dd>
  @Html.DisplayFor(model => model.Author)
 </dd> 

 </dl> 

 @using (Html.BeginForm()) {
 @Html.AntiForgeryToken() 

 <div class="form-actions no-color">
  <input type="submit" value="Delete" class="btn btn-default" /> |
  @Html.ActionLink("返回列表", "Index")
 </div>
 }
</div>

Create.cshtml:

@model Library.Web.Models.Book 

@{
 ViewBag.Title = "Create";
 Layout = "~/Views/Shared/_Layout.cshtml";
} 

<h2>创建</h2> 

@using (Html.BeginForm())
{
 @Html.AntiForgeryToken() 

 <div class="form-horizontal">
 <h4>Book</h4>
 <hr />
 @Html.ValidationSummary(true) 

 <div class="form-group">
  @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.EditorFor(model => model.Title)
  @Html.ValidationMessageFor(model => model.Title)
  </div>
 </div> 

 <div class="form-group">
  @Html.LabelFor(model => model.Foreword, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.TextAreaFor(model => model.Foreword)
  @Html.ValidationMessageFor(model => model.Foreword)
  </div>
 </div> 

 <div class="form-group">
  @Html.LabelFor(model => model.Pages, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.EditorFor(model => model.Pages)
  @Html.ValidationMessageFor(model => model.Pages)
  </div>
 </div> 

 <div class="form-group">
  @Html.LabelFor(model => model.Author, new { @class = "control-label col-md-2" })
  <div class="col-md-10">
  @Html.EditorFor(model => model.Author)
  @Html.ValidationMessageFor(model => model.Author)
  </div>
 </div> 

 <div class="form-group">
  <div class="col-md-offset-2 col-md-10">
  <input type="submit" value="创建" class="btn btn-default" />
  </div>
 </div>
 </div>
} 

<div>
 @Html.ActionLink("回到列表", "Index")
</div> 

@section Scripts {
 @Scripts.Render("~/bundles/jqueryval")
}

Home->Index.cshtml

@model Library.Web.ViewModels.SearchViewModel
@{
 ViewBag.Title = "Elasticsearch";
} 

<div class="jumbotron">
 <h1>Elasticsearch入门</h1>
 <p class="lead">安装和配置群集</p>
 <ol>
 <li>
  <a href="http://www.oracle.com/technetwork/java/
javase/downloads/index.html">安装Java</a>
 </li>
 <li>
  <a href="http://www.elasticsearch.org/
download/">安装Elasticsearch</a>
 </li>
 <li>运行Elasticsearch</li>
 <li><a href="/Books/Create">增加一些书籍</a></li>
 </ol>
</div> 

@if (Model == null)
{
 return;
}
<div style="margin-top: 30px;">
 @if (Model.Suggestions.Any(x => x.Key == "did-you-mean"))
 {
 <span>你的意思是: </span>
 foreach (var suggestions in Model.Suggestions["did-you-mean"])
 {
  var count = 0;
  foreach (var suggestion in suggestions.Options)
  {
  <a href="/Home/Search?query=@suggestion.Text"><strong>@suggestion.Text </strong> </a>
  count++;
  }
  if (count == 0)
  {
  <span class="alert-danger">没有建议!</span>
  } 

 }
 }
</div> 

<h3><strong>Results for:</strong> @Model.Query</h3> 

@if (Model != null)
{
 <table class="table table-condensed">
 <thead>
  <tr><th>文档的分数(排名相关度)</th><th>Title</th><th>Content</th><th>Author</th></tr>
 </thead> 

 <tbody>
  @foreach (var result in Model.Results)
  {
  <tr>
   <td>@result.Score</td>
   <td>
   <a href="/Books/Details/@result.Id">
    @if (result.Highlights != null && result.Highlights.Any(x => x.Key == "title"))
    {
    var hl = result.Highlights.FirstOrDefault(x => x.Key == "title");
    foreach (var h in hl.Value.Highlights)
    {
     WriteLiteral(h);
    }
    }
    else
    {
    WriteLiteral(result.Source.Title);
    }
   </a>
   </td> 

   <td>
   @if (result.Highlights != null && result.Highlights.Any(x => x.Key == "foreword"))
   {
    var hl = result.Highlights.FirstOrDefault(x => x.Key == "foreword");
    foreach (var h in hl.Value.Highlights)
    {
    WriteLiteral(h + "...");
    }
   } 

   </td> 

   <td>@result.Source.Author</td>
  </tr> 

  }
  @if (!Model.Results.Any())
  {
  <tr>
   <td colspan="4" class="alert alert-danger" style="text-align:center;">没有结果发现:(</td>
  </tr>
  }
 </tbody> 

 </table>
 <h4><span class="label label-default">@Model.Results.Count()</span>搜索结果用了 @Model.Elapsed 毫秒</h4>
}

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>@ViewBag.Title</title>
 @Styles.Render("~/Content/css")
 @Scripts.Render("~/bundles/modernizr") 

</head>
<body>
 <div class="navbar navbar-inverse navbar-fixed-top">
 <div class="container">
  <div class="navbar-header">
  <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
   <span class="icon-bar"></span>
   <span class="icon-bar"></span>
   <span class="icon-bar"></span>
  </button>
  @Html.ActionLink("Elasticsearch MVC示例", "Index", "Home", null, new { @class = "navbar-brand" })
  </div>
  <div class="navbar-collapse collapse">
  <ul class="nav navbar-nav">
   <li>@Html.ActionLink("Home", "Index", "Home")</li>
   <li>@Html.ActionLink("Books", "Index", "Books")</li>
  </ul> 

  @using (Html.BeginForm("Search", "Home", FormMethod.Get,new {@class = "navbar-form navbar-left"}))
  {
   <div class="form-group">
   <input class="form-control" type="text" placeholder="搜索" name="query" />
   </div>
   <button type="submit" class="btn btn-default">提交</button>
  } 

  </div> 

 </div>
 </div>
 <div class="container body-content">
 @RenderBody()
 <hr />
 <footer>
  <p>© @DateTime.Now.Year - Elasticsearch, Nest, ASP.NET 应用</p>
 </footer>
 </div> 

 @Scripts.Render("~/bundles/jquery")
 @Scripts.Render("~/bundles/bootstrap")
 @RenderSection("scripts", required: false)
</body>
</html>

结果如图:

列表页

创建页:

搜索结果页:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • elasticsearch插件开发教程

    检索引擎Elasticsearch支持插件模式.有些时候你可能须要安装一些插件.甚至自己开发插件,这里就提供一个開始ES插件开发演示样例,ES版本号为1.5.2. 一.插件类继承自org.elasticsearch.plugins.AbstractPlugin package org.elasticsearch.plugin.helloworld; import java.util.ArrayList; import java.util.Collection; import java.util.

  • SpringBoot整合ElasticSearch实践

    本节我们基于一个发表文章的案例来说明SpringBoot如何elasticsearch集成.elasticsearch本身可以是一个独立的服务,也可以嵌入我们的web应用中,在本案例中,我们讲解如何将elasticsearch嵌入我们的应用中. 案例背景:每个文章(Article)都要属于一个教程(Tutorial),而且每个文章都要有一个作者(Author). 一.实体设计: Tutorial.java public class Tutorial implements Serializable

  • 基于Lucene的Java搜索服务器Elasticsearch安装使用教程

    一.安装Elasticsearch Elasticsearch下载地址:http://www.elasticsearch.org/download/ ·下载后直接解压,进入目录下的bin,在cmd下运行elasticsearch.bat 即可启动Elasticsearch ·用浏览器访问: http://localhost:9200/   ,如果出现类似如下结果则说明安装成功: { "name" : "Benedict Kine", "cluster_na

  • centos下root运行Elasticsearch异常问题解决

     在CentOS 6.5 上运行Elasticsearch 2.3,异常如下: Exception in thread "main" java.lang.RuntimeException: don't run elasticsearch as root. at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:93) at org.elasticsearch.bootstrap.Bootstra

  • 详解spring中使用Elasticsearch的代码实现

    在使用Elasticsearch之前,先给大家聊一点干货. 1.      ES和solr都是作为全文搜索引擎出现的.都是基于Lucene的搜索服务器. 2.   ES不是可靠的存储系统,不是数据库,它有丢数据的风险. 3.  ES不是实时系统,数据写入成功只是trans log成功(类似于MySQL的bin log),写入成功后立刻查询查不到是正常的.因为数据此刻可能还在内存里而不是进入存储引擎里.同理,删除一条数据后也不是马上消失.写入何时可查询?ES内部有一个后台线程,定时将内存中的一批数

  • 详解centos7虚拟机安装elasticsearch5.0.x-安装篇

    centos7虚拟机安装elasticsearch5.0.x-安装篇 请预先安装jdk详细步骤请参考:http://www.jb51.net/softjc/193398.html 创建新用户(非root用户) elasticsearch只能用非root启动,这里我创建了一个叫seven的用户 [root@localhost ~]# useradd seven [root@localhost ~]# passwd seven 下载elasticsearch [root@localhost ~]#

  • 详解spring-boot集成elasticsearch及其简单应用

    介绍 记录将elasticsearch集成到spring boot的过程,以及一些简单的应用和helper类使用. 接入方式 使用spring-boot中的spring-data-elasticsearch,可以使用两种内置客户端接入 1.节点客户端(node client): 配置文件中设置为local:false,节点客户端以无数据节点(node-master或node-client)身份加入集群,换言之,它自己不存储任何数据,但是它知道数据在集群中的具体位置,并且能够直接转发请求到对应的节

  • 安装ElasticSearch搜索工具并配置Python驱动的方法

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二流行的企业搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便. 我们建立一个网站或应用程序,并要添加搜索功能,令我们受打击的是:搜索工作是很难的.我们希望我们的搜索解决方案要快,我们希望有一个零配置和一个完全免费的搜索模式,我们希望能够简单

  • spring 操作elasticsearch查询使用方法

    最近学习了一下elasticsearch使用,网上的资料又很少,真是一个头两个大.好歹最后终于了解了.留个笔记做日后查询. package com.gooddeep.dev.elasticsearch.commons.dao; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.elasticsearch.action.ActionFuture; import org.elasti

  • Elasticsearch.Net使用入门教程(1)

    本文实例为大家分享了Elasticsearch.Net使用教程,供大家参考,具体内容如下 首先去官网下载Elasticsearch 2.3.4安装包,解压后,在cmd命令行进入安装目录,再进入 bin目录,运行elasticsearch.bat命令. elasticsearch插件elasticsearch-head安装: bin目录下执行命令plugin -install mobz/elasticsearch-head 然后开始.net编程,构建控制台应用程序 Program.cs代码如下:

随机推荐