ElasticsearchCRUD使用(二)【简单的文档进行搜索的MVC应用程序】

作者:神秘网友 发布时间:2020-09-08 10:33:19

ElasticsearchCRUD使用(二)【简单的文档进行搜索的MVC应用程序】

ElasticsearchCRUD使用(二)【简单的文档进行搜索的MVC应用程序】

搜索Elasticsearch中的文档

该应用程序使用ElasticsearchCRUD访问Elasticsearch。 API可以使用任何DTO或实体类,并将其自动映射到Elasticsearch索引并使用类类型键入。 默认索引是类的类型,所有字符都转换为小写字符。 默认类型是小写字符的类型名称。 如果Elasticsearch需要不同的映射,这可以很容易地改变。 例如,在Elasticsearch中保存为子文档的类需要其索引的映射,即。 使用存储父文档的索引。

在这个例子中使用了一个Skill 类。 这个类被保存在搜索引擎中,具有索引skills和类型skill

public class Skill
{
  [Required]
  [Range(1, long.MaxValue)]
  public long Id { get; set; }

  [Required]
  public string Name { get; set; }

  [Required]
  public string Description { get; set; }

  public DateTimeOffset Created { get; set; }

  public DateTimeOffset Updated { get; set; }
}

ElasticsearchCRUD Search方法用于使用QueryString进行全文搜索。 该方法从SearchController获取 term(s),并在引擎中执行QueryString搜索。 此搜索不区分大小写。

您可以使用context.Search方法几乎可以进行任何搜索,而不仅仅是查询字符串搜索。 不支持高亮显示的结果,不支持多个索引或多个类型搜索。 所有您需要做的是为搜索构建JSON查询,并从匹配中返回类型的集合。 查询是使用Search类构建的。 Query属性定义可以使用通配符的查询字符串搜索。

public IEnumerable<Skill> QueryString(string term)
{
    var results = _context.Search<Skill>(BuildQueryStringSearch(term));
        return results.PayloadResult.Hits.HitsResult.Select(t => t.Source);
}

private ElasticsearchCRUD.Model.SearchModel.Search BuildQueryStringSearch(string term)
{
    var names = "";
    if (term != null)
    {
        names = term.Replace("+", " OR *");
    }

    var search = new ElasticsearchCRUD.Model.SearchModel.Search
    {
        Query = new Query(new QueryStringQuery(names + "*"))
    };

    return search;
}

搜索方法用于MVC SearchControllerJson被返回,因为jQuery Autocomplete 控件使用了action方法。

public JsonResult Search(string term)
{           
  return Json(_searchProvider.QueryString(term), "Skills", JsonRequestBehavior.AllowGet);
}

Autocomplete(jquery-ui)源方法使用SearchController中的操作方法搜索。 这将对象数组保存到autocomplete控件。 此控件需要控件的每个项中的标签和值属性。 select方法用于从搜索中选择一个结果。 然后将所选项目添加到页面上的其他html控件,以更新或删除HTTP请求。

<fieldset class="form">
    <legend>SEARCH for a document in the search engine</legend>
    <table width="500">
        <tr>
            <th></th>
        </tr>
        <tr>
            <td>
                <label for="autocomplete">Search: </label>
            </td>
        </tr>
        <tr>
            <td>
                <input id="autocomplete" type="text" style="width:500px" />
            </td>
        </tr>
    </table>
</fieldset>

@section scripts
{
    <script type="text/javascript">
        var items;
        $(document).ready(function() {
            $("input#autocomplete").autocomplete({
                source: function(request, response) {
                    $.ajax({
                        url: "search",
                        dataType: "json",
                        data: {
                            term: request.term,
                        },
                        success: function(data) {
                            var itemArray = new Array();
                            for (i = 0; i < data.length; i++) {
                                itemArray[i] = { label: data[i].Name, value: data[i].Name, data: data[i] }
                            }

                            console.log(itemArray);
                            response(itemArray);
                        },
                        error: function(data, type) {
                            console.log(type);
                        }
                    });
                },
                select: function (event, ui) {
                    $("#spanupdateId").text(ui.item.data.Id);
                    $("#spanupdateCreated").text(new Date(parseInt(ui.item.data.Created.substr(6))));
                    $("#spanupdateUpdated").text(new Date(parseInt(ui.item.data.Updated.substr(6))));

                    $("#updateName").text(ui.item.data.Name);
                    $("#updateDescription").text(ui.item.data.Description);
                    $("#updateName").val(ui.item.data.Name);
                    $("#updateDescription").val(ui.item.data.Description);

                    $("#updateId").val(ui.item.data.Id);
                    $("#updateCreated").val(ui.item.data.Created);
                    $("#updateUpdated").val(ui.item.data.Updated);

                    $("#spandeleteId").text(ui.item.data.Id);
                    $("#deleteId").val(ui.item.data.Id);
                    $("#deleteName").text(ui.item.data.Name);

                    console.log(ui.item);
                }
            });
        });
</script>
}

然后可以使用以下控件:
ElasticsearchCRUD使用(二)【简单的文档进行搜索的MVC应用程序】

Elasticsearch创建,更新和删除

为了方便搜索和提供一些数据,使用ElasticsearchCRUD添加了创建,更新和删除实现。 提供者使用ElasticsearchCRUD的上下文,并在一个批量请求中执行所有待处理的更改到Elasticsearch。 多个索引,类型可以在单个上下文中执行批量请求。 HttpClient类在上下文中心下使用。 在Elasticsearch中添加或更改大量数据时,效果很好。

private const string ConnectionString = "http://localhost:9200/";
private readonly IElasticsearchMappingResolver _elasticsearchMappingResolver = new ElasticsearchMappingResolver();

public void AddUpdateEntity(Skill skill)
{
   using (var context = new ElasticsearchContext(ConnectionString, _elasticsearchMappingResolver))
   {
       context.AddUpdateDocument(skill, skill.Id);
       context.SaveChanges();
   }
}

public void UpdateSkill(long updateId, string updateName, string updateDescription)
{
  using (var context = new ElasticsearchContext(ConnectionString, _elasticsearchMappingResolver))
  {
      var skill = context.GetDocument<Skill>(updateId);
      skill.Updated = DateTime.UtcNow;
      skill.Name = updateName;
      skill.Description = updateDescription;
      context.AddUpdateDocument(skill, skill.Id);
      context.SaveChanges();
  }
}

public void DeleteSkill(long deleteId)
{
   using (var context = new ElasticsearchContext(ConnectionString, _elasticsearchMappingResolver))
   {
       context.DeleteDocument<Skill>(deleteId);
       context.SaveChanges();
   }
}

这可以在SearchController中使用。 HTTP Post Index操作方法中的创建skill文档已经实现了验证。 这调用ElasticsearchCRUD的AddUpdateDocument方法。 如果搜索引擎中已存在具有相同ID的文档,则文档将被覆盖。 通常实体来自主数据库,并保存elasticsearch以进行最佳搜索。 主数据库管理该实体的Ids,因此这不是该用例的问题。

readonly ISearchProvider _searchProvider = new ElasticSearchProvider();

[HttpGet]
public ActionResult Index()
{
   return View();
}

[HttpPost]
public ActionResult Index(Skill model)
{
  if (ModelState.IsValid)
  {
    model.Created = DateTime.UtcNow;
    model.Updated = DateTime.UtcNow;
    _searchProvider.AddUpdateDocument(model);

    return Redirect("Search/Index");
  }

  return View("Index", model);
}

[HttpPost]
public ActionResult Update(long updateId, string updateName, string updateDescription)
{
   _searchProvider.UpdateSkill(updateId, updateName, updateDescription);
   return Redirect("Index");
}

[HttpPost]
public ActionResult Delete(long deleteId)
{
   _searchProvider.DeleteSkill(deleteId);
   return Redirect("Index");
}

然后可以在视图中使用控制器。 视图有3种不同的形式:创建,删除和更新。 当从Autocomplete控件中选择搜索结果时,删除和更新表单将被更新。

<form name="input" action="update" method="post">
    <fieldset class="form">
        <legend>UPDATE an existing document in the search engine</legend>
        <table width="500">
            <tr>
                <th></th>
                <th></th>
            </tr>
            <tr>
                <td>
                    <span>Id:</span>
                </td>
                <td>
                    <span id="spanupdateId">-</span>
                    <input id="updateId" name="updateId" type="hidden" />
                </td>
            </tr>
            <tr>
                <td>
                    <span>Name:</span>
                </td>
                <td>
                    <input id="updateName" name="updateName" type="text" />
                </td>
            </tr>
            <tr>
                <td>
                    <span>Description:</span>
                </td>
                <td>
                    <input id="updateDescription" name="updateDescription" type="text" />
                </td>
            </tr>
            <tr>
                <td>
                    <span>Created:</span>
                </td>
                <td>
                    <span id="spanupdateCreated">-</span>
                    <input id="updateCreated" name="updateCreated" type="hidden" />
                </td>
            </tr>
            <tr>
                <td>
                    <span>Updated:</span>
                </td>
                <td>
                    <span id="spanupdateUpdated">-</span>
                    <input id="updateUpdated" name="updateUpdated" type="hidden" />
                </td>
            </tr>
            <tr>
                <td>
                    <br />
                    <input type="submit" value="Update Skill" style="width: 200px" />
                </td>
                <td></td>
            </tr>
        </table>
    </fieldset>
</form>

<form name="input" action="delete" method="post">
    <fieldset class="form">
        <legend>DELETE an existing document in the search engine</legend>
        <table width="500">
            <tr>
                <th></th>
                <th></th>
            </tr>
            <tr>
                <td>
                    <span id="deleteName">-</span>
                </td>
                <td>
                    <span id="spandeleteId">-</span>
                    <input id="deleteId" name="deleteId" type="hidden" />
                </td>
            </tr>

            <tr>
                <td>
                    <br />
                    <input type="submit" value="Delete Skill" style="width: 200px" />
                </td>
                <td></td>
            </tr>
        </table>
    </fieldset>
</form>

@using (Html.BeginForm("Index", "Search"))
{
    @Html.ValidationSummary(true)

    <fieldset class="form">
        <legend>CREATE a new document in the search engine</legend>
        <table width="500">
            <tr>
                <th></th>
                <th></th>
            </tr>
            <tr>
                <td>
                    @Html.Label("Id:")
                </td>
                <td>
                    @Html.EditorFor(model => model.Id)
                    @Html.ValidationMessageFor(model => model.Id)
                </td>
            </tr>
            <tr>
                <td>
                    @Html.Label("Name:")
                </td>
                <td>
                    @Html.EditorFor(model => model.Name)
                    @Html.ValidationMessageFor(model => model.Name)
                </td>
            </tr>
            <tr>
                <td>
                    @Html.Label("Description:")
                </td>
                <td>
                    @Html.EditorFor(model => model.Description)
                    @Html.ValidationMessageFor(model => model.Description)
                </td>
            </tr>
            <tr>
                <td>
                    <br />
                    <input type="submit" value="Add Skill" style="width:200px" />
                </td>
                <td></td>
            </tr>
        </table>
    </fieldset>
}

然后可以在浏览器中使用该应用程序,如下所示:
ElasticsearchCRUD使用(二)【简单的文档进行搜索的MVC应用程序】

结论

正如你所看到的,使用具有Elasticsearch的ASP.NET MVC进行全文搜索是非常容易的。 这可以很容易地改变为使用Web API与Angular JS。 由于这些规模很好,性能很好,您可以将其用于几乎任何应用程序。

ElasticsearchCRUD使用(二)【简单的文档进行搜索的MVC应用程序】相关教程

  1. 简单介绍HTML5 Landmark
  2. 使用git命令上传本地项目到github
  3. 自动化运维使用cobbler实现大PXE
  4. ElasticsearchCRUD使用(四)【使用EF从SQLServer到Elasticsearch
  5. 【Java邮件开发】6.使用Authenticator和send静态方法
  6. MAC下Apktool、dex2jar、jd-gui的安装和简单使用
  7. java集合简介
  8. RT-ThreadPM组件移植与使用-使能PM组件