Elasticsearch.Net 사용 튜 토리 얼 MVC 4 도서 관리 시스템(2)
23893 단어 Elasticsearch.NetMVC4관리 시스템
우선 프로젝트 구성 도:
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 와 Books Controller.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"; }
}
}
Search Service.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;
}
}
보기 보기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/[email protected]"><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>
결 과 는 그림 과 같다.리스트 페이지
생 성 페이지:
검색 결과 페이지:
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Embulk를 사용하여 ElasticCloud로 보내기Embulk에서 ElasticCloud에 보낼 수 있을까라고 생각비망록도 겸해 기술을 남깁니다 Embulk 설치 ElasticCloud (14 일 체험판) brew라면 아래 명령 입력 파일 만들기 파일 내용 seed...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.