ElasticsearchCRUD使用(六)【EF和Elasticsearch的MVC应用程序】

es中ElasticsearchRepository 的原理和使用 把数据存储到es中,有两种方式一种是ElasticsearchRepository 接口,另一种是ElasticsearchTemplate接口,今天我们主要分析ElasticsearchRepository接口。 一、ElasticsearchRepository 原理分析: 1、首先springBoot 项目的pom文件中引入jar包: <!-- ES搜索 --> <dependency> <groupId>org.s. 阅读详情

本文演示如何使用实体框架与MS SQL Server作为主数据库和Elasticsearch搜索/选择功能。该应用程序结合了Elasticsearch的功能,用于搜索和快速选择,以及用于CUD事务(创建,更新和删除)的实体框架。

设置文档搜索引擎

AdventureWorks2012用于填充搜索引擎的数据。可以在这里下载。

MS SQL Server是主数据库。数据需要加载到Elasticsearch中,而辅助持久化需要被初始化。在应用程序生命周期开始时,此任务通常只执行一次。以下方法使用实体框架读取所需的数据,并将其保存到Elasticsearch的批量请求中。 JsonIgnore和Key属性被添加到实体类。作为子文档保存到Elasticsearch的实体需要主键的Key属性。所有不支持的属性或不需要的属性都用JsonIgnore属性标记。

using System;
using System.Diagnostics;
using System.Linq;
using ElasticsearchCRUD;
using ElasticsearchCRUD.Tracing;
using WebSearchWithElasticsearchEntityFrameworkAsPrimary.DomainModel;

namespace WebSearchWithElasticsearchEntityFrameworkAsPrimary.Search
{
    public class InitializeSearchEngine
    {
        private readonly Stopwatch _stopwatch = new Stopwatch();

        public void SaveToElasticsearchStateProvinceIfitDoesNotExist()
        {
            IElasticsearchMappingResolver elasticsearchMappingResolver = new ElasticsearchMappingResolver();
            using (var elasticSearchContext = new ElasticsearchContext("http://localhost:9200/", new ElasticsearchSerializerConfiguration(elasticsearchMappingResolver, true, true)))
            {
                if (!elasticSearchContext.IndexTypeExists<StateProvince>())
                {
                   elasticSearchContext.TraceProvider = new ConsoleTraceProvider();
                   using (var databaseEfModel = new EfModel())
                   {
                    int pointer = 0;
                    const int interval = 20;
                    bool firstRun = true;
                    int length = databaseEfModel.StateProvince.Count();

                    while (pointer < length)
                    {
                        _stopwatch.Start();
                        var collection = databaseEfModel.StateProvince.OrderBy(t => t.StateProvinceID).Skip(pointer).Take(interval).ToList<StateProvince>();
                        _stopwatch.Stop();
                        Console.WriteLine("Time taken for select {0} Address: {1}", interval, _stopwatch.Elapsed);
                        _stopwatch.Reset();

                        _stopwatch.Start();
                        foreach (var item in collection)
                        {
                            var ee = item.CountryRegion.Name;
                            elasticSearchContext.AddUpdateDocument(item, item.StateProvinceID);
                        }

                        if (firstRun)
                        {
                            elasticSearchContext.SaveChangesAndInitMappingsForChildDocuments();
                            firstRun = false;
                        }
                        else
                        {
                            elasticSearchContext.SaveChanges();
                        }

                        _stopwatch.Stop();
                        Console.WriteLine("Time taken to insert {0} Address documents: {1}", interval, _stopwatch.Elapsed);
                        _stopwatch.Reset();
                        pointer = pointer + interval;
                        Console.WriteLine("Transferred: {0} items", pointer);
                    }
                }
            }
           }
        }

    }
}

此方法的调用是全局asax Application_Start方法。 这也可以部署为单独的Windows服务或可以随时调用的控制台应用程序,并且还可以间隔提供验证检查,并对两个持久层执行一些管理或完整性检查。

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using WebSearchWithElasticsearchEntityFrameworkAsPrimary.Search;

namespace WebSearchWithElasticsearchEntityFrameworkAsPrimary
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            var initializeSearchEngine = new InitializeSearchEngine();
            initializeSearchEngine.SaveToElasticsearchStateProvinceIfitDoesNotExist();

            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}

使用实体框架 code first 从现有数据库创建Address类。 Key和JsonIgnore属性已添加到ElasticsearchCRUD序列化所需的属性。 应用程序使用所有层的address类。 通常,view model类将直接用于视图而不是实体类。 BusinessEntityAddress已经从搜索引擎中删除,因为在此应用程序中搜索不是必需的。

using Newtonsoft.Json;

namespace WebSearchWithElasticsearchEntityFrameworkAsPrimary.DomainModel
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    [Table("Person.Address")]
    public partial class Address
    {
        public Address()
        {
            BusinessEntityAddress = new HashSet<BusinessEntityAddress>();
        }

        [Key]
        public int AddressID { get; set; }

        [Required]
        [StringLength(60)]
        public string AddressLine1 { get; set; }

        [StringLength(60)]
        public string AddressLine2 { get; set; }

        [Required]
        [StringLength(30)]
        public string City { get; set; }

        public int StateProvinceID { get; set; }

        [Required]
        [StringLength(15)]
        public string PostalCode { get; set; }

        [JsonIgnore]
        public DbGeography SpatialLocation { get; set; }

        public Guid rowguid { get; set; }

        public DateTime ModifiedDate { get; set; }

        public virtual StateProvince StateProvince { get; set; }

        [JsonIgnore]
        public virtual ICollection<BusinessEntityAddress> BusinessEntityAddress { get; set; }
    }
}

Search Provider

因为同一个类可以用于EF和ElasticsearchCRUD,这使得在两个持久层中更新,创建或删除实体/文档非常容易。 实体上下文和elasticsearchCRUD上下文都在ElasticsearchProvider的构造函数中初始化。 Address类需要一个ElasticsearchMappingAddress,因为Address类被保存为Elasticsearch中StateProvince的子节点。

private const string ConnectionString = "http://localhost:9200/";
private readonly IElasticsearchMappingResolver _elasticsearchMappingResolver;
private readonly ElasticsearchContext _elasticsearchContext;
private readonly EfModel _entityFrameworkContext;

public ElasticsearchProvider()
{
    _elasticsearchMappingResolver = new ElasticsearchMappingResolver();
    _elasticsearchMappingResolver.AddElasticSearchMappingForEntityType(typeof(Address), new ElasticsearchMappingAddress());
    _elasticsearchContext = new ElasticsearchContext(ConnectionString, new ElasticsearchSerializerConfiguration(_elasticsearchMappingResolver,true,true));
    _entityFrameworkContext = new EfModel();
}

ElasticsearchMappingAddress需要定义父索引。 这样做如下:

using System;
using ElasticsearchCRUD;

namespace WebSearchWithElasticsearchEntityFrameworkAsPrimary.Search
{
    public class ElasticsearchMappingAddress : ElasticsearchMapping
    {
        // This address type is a child type form stateprovince in the stateprovinces index
        public override string GetIndexForType(Type type)
        {
            return "stateprovinces";
        }
    }
}

现在可以为搜索提供者实现创建,更新和删除方法。这需要对标准EF repository进行小的更改。在Elasticsearch中搜索或找到address 项。这些文档结果未附加到EF上下文中。因此,当需要CUD操作时,需要从主数据库附加或获取数据项。有不同的方法来做到这一点。

EF事务在Elasticsearch动作之前完成。我们只需要主数据库中存在的Elasticsearch中的数据。辅助数据库可能与主数据库不同步。您需要管理作业,并根据需要修复辅助层。应用程序的系统要求将定义如何完成。例如,如果它是一个国家的政府部门的应用程序,您可以在晚上执行此操作,而不必担心实时数据更改。对于全球应用,您需要实时操作。

public void AddUpdateDocument(Address address)
{
    address.ModifiedDate = DateTime.UtcNow;
    address.rowguid = Guid.NewGuid();
    var entityAddress = _entityFrameworkContext.Address.Add(address);
    _entityFrameworkContext.SaveChanges();

    //我们使用具有适当ID的实体结果
    _elasticsearchContext.AddUpdateDocument(entityAddress, entityAddress.AddressID, entityAddress.StateProvinceID);
    _elasticsearchContext.SaveChanges();
}

public void UpdateAddresses(long stateProvinceId, List<Address> addresses)
{
    foreach (var item in addresses)
    {
        // 如果父类已经更改,则需要删除该子类并再次创建。 这在这个例子中不是必需的
        var addressItem = _elasticsearchContext.SearchById<Address>(item.AddressID);
        // 需要在这里更新一个实体
        var entityAddress = _entityFrameworkContext.Address.First(t => t.AddressID == addressItem.AddressID);

        if (entityAddress.StateProvinceID != addressItem.StateProvinceID)
        {
            _elasticsearchContext.DeleteDocument<Address>(addressItem.AddressID, new RoutingDefinition { ParentId = stateprovinceid });
        }

        entityAddress.AddressLine1 = item.AddressLine1;
        entityAddress.AddressLine2 = item.AddressLine2;
        entityAddress.City = item.City;
        entityAddress.ModifiedDate = DateTime.UtcNow;
        entityAddress.PostalCode = item.PostalCode;
        item.rowguid = entityAddress.rowguid;
        item.ModifiedDate = DateTime.UtcNow;

        _elasticsearchContext.AddUpdateDocument(item, item.AddressID, item.StateProvinceID);
    }

    _entityFrameworkContext.SaveChanges();
    _elasticsearchContext.SaveChanges();
}

public void DeleteAddress(int addressId, int stateprovinceid)
{       
    var address = new Address { AddressID = addressId };
    _entityFrameworkContext.Address.Attach(address);
    _entityFrameworkContext.Address.Remove(address);

    _entityFrameworkContext.SaveChanges();

    _elasticsearchContext.DeleteDocument<Address>(addressId, new RoutingDefinition { ParentId = stateprovinceid });
    _elasticsearchContext.SaveChanges();
}

在上一个示例中,MVC控制器中的提供程序就像以前一样使用。 控制器提供StateProvince搜索,并且当选择省份时,将使用jTable的列表操作从Elasticsearch检索子address 对象,并根据需要进行排序或分页。Address 搜索如下:

public PagingTableResult<Address> GetAllAddressesForStateProvince(string stateprovinceid, int jtStartIndex, int jtPageSize, string jtSorting)
{
    var result = new PagingTableResult<Address>();
    var data = _elasticsearchContext.Search<Address>(
                    BuildSearchForChildDocumentsWithIdAndParentType(
                        stateprovinceid, 
                        "stateprovince",
                        jtStartIndex, 
                        jtPageSize, 
                        jtSorting)
                );

    result.Items = data.PayloadResult.ToList();
    result.TotalCount = data.TotalHits;
    return result;
}

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

// {
//  "from": 0, "size": 10,
//  "query": {
//  "term": { "_parent": "parentdocument#7" }
//  },
//  "sort": { "city" : { "order": "desc" } }"
// }
private Search BuildSearchForChildDocumentsWithIdAndParentType(object parentId, string parentType, int jtStartIndex, int jtPageSize, string jtSorting)
{
    var search = new Search
    {
        From = jtStartIndex,
        Size = jtPageSize,
        Query = new Query(new TermQuery("_parent", parentType + "#" + parentId))    
    };

    var sorts = jtSorting.Split(' ');
    if (sorts.Length == 2)
    {
        var order = OrderEnum.asc;
        if (sorts[1].ToLower() == "desc")
        {
            order = OrderEnum.desc;
        }

        search.Sort = CreateSortQuery(sorts[0].ToLower(), order);
    }
    return search;
}

public SortHolder CreateSortQuery(string sort, OrderEnum order)
{
    return new SortHolder(
        new List<ISort>
        {
            new SortStandard(sort)
            {
                Order = order
            }
        }
    );
}

搜索控制器非常简单。 它为视图提供所有操作,并根据需要调用提供程序方法:

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using WebSearchWithElasticsearchEntityFrameworkAsPrimary.DomainModel;
using WebSearchWithElasticsearchEntityFrameworkAsPrimary.Search;

namespace WebSearchWithElasticsearchEntityFrameworkAsPrimary.Controllers
{
    [RoutePrefix("Search")]
    public class SearchController : Controller
    {
        readonly ISearchProvider _searchProvider = new ElasticsearchProvider();

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

        [Route("Search")]
        public JsonResult Search(string term)
        {
            return Json(_searchProvider.QueryString<StateProvince>(term), "AddressListForStateProvince", JsonRequestBehavior.AllowGet);
        }

        [Route("GetAddressForStateProvince")]
        public JsonResult GetAddressForStateProvince(string stateprovinceid, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                var data = _searchProvider.GetAllAddressesForStateProvince(stateprovinceid, jtStartIndex, jtPageSize, jtSorting);
                return Json(new { Result = "OK", Records = data.Items, TotalRecordCount = data.TotalCount });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [Route("CreateAddressForStateProvince")]
        public JsonResult CreateAddressForStateProvince(Address address, string stateprovinceid)
        {
            try
            {
                address.StateProvinceID = Convert.ToInt32(stateprovinceid);
                _searchProvider.AddUpdateDocument(address);
                return Json(new { Result = "OK", Record = address });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [Route("UpdateAddressForStateProvince")]
        public JsonResult UpdateAddressForStateProvince(Address address)
        {
            try
            {
                _searchProvider.UpdateAddresses(address.StateProvinceID, new List<Address> { address });
                return Json(new { Result = "OK", Records = address });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [HttpPost]
        [Route("DeleteAddress")]
        public ActionResult DeleteAddress(int addressId, int stateprovinceid)
        {
            _searchProvider.DeleteAddress(addressId, stateprovinceid);
            return Json(new { Result = "OK"});
        }
    }
}

然后可以在视图中使用MVC控制器。 razor html视图创建autocomplete 控件以及来自所选StateProvince的address 子项的jTable。
注意:所需的JavaScript库和CSS文件都包含在MVC包中。

@model WebSearchWithElasticsearchEntityFrameworkAsPrimary.Models.SearchModel

<br/>

<fieldset class="form">
    <legend></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>

<div id="addressResultsForStateProvince" />
<input name="selectedstateprovinceid" id="selectedstateprovinceid" type="hidden" value="" />

@section scripts
{
    <link href="http://localhost:49908/Content/themes/flat/jquery-ui-1.10.3.min.css" rel="stylesheet" />
    <link href="~/Scripts/jtable/themes/jqueryui/jtable_jqueryui.min.css" rel="stylesheet" />
    <script type="text/javascript">


        function RefreshPage() {
            $('#addressResultsForStateProvince').jtable('load', { selectedstateprovinceid: $('#selectedstateprovinceid').val() });
        }

        $('#addressResultsForStateProvince').jtable({
            title: 'Address list of selected StateProvince',
            paging: true,
            pageSize: 10,
            sorting: true,
            multiSorting: true,
            defaultSorting: 'ModifiedDate desc',
            actions: {
                listAction: function (postData, jtParams) {
                    return $.Deferred(function ($dfd) {
                        $.ajax({
                            url: 'http://localhost:49908/Search/GetAddressForStateProvince?stateprovinceid=' + $('#selectedstateprovinceid').val() + '&jtStartIndex=' + jtParams.jtStartIndex + '&jtPageSize=' + jtParams.jtPageSize + '&jtSorting=' + jtParams.jtSorting,
                            type: 'POST',
                            dataType: 'json',
                            data: postData,
                            success: function (data) {
                                $dfd.resolve(data);
                            },
                            error: function () {
                                $dfd.reject();
                            }
                        });
                    });
                },
                deleteAction: function (postData, jtParams) {
                    return $.Deferred(function ($dfd) {
                        $.ajax({
                            url: 'http://localhost:49908/Search/DeleteAddress?addressId=' + postData.AddressID + "&stateprovinceid=" + $('#selectedstateprovinceid').val(),
                            type: 'POST',
                            dataType: 'json',
                            data: postData,
                            success: function (data) {
                                $dfd.resolve(data);
                            },
                            error: function () {
                                $dfd.reject();
                            }
                        });
                    });
                },
                createAction: function (postData) {
                    var resultData = $.ajax({
                        url: 'http://localhost:49908/Search/CreateAddressForStateProvince?stateprovinceid=' + $('#selectedstateprovinceid').val(),
                        type: 'POST',
                        dataType: 'json',
                        data: postData,
                        success: function (data) {
                            return data;
                        },
                        error: function () {

                        }
                    });

                    return resultData;
                },
                updateAction: function (postData) {
                    var resultData = $.ajax({
                        url: 'http://localhost:49908/Search/UpdateAddressForStateProvince?stateprovinceid=' + $('#selectedstateprovinceid').val(),
                        type: 'POST',
                        dataType: 'json',
                        data: postData,
                        success: function (data) {
                            return data;
                        },
                        error: function () {

                        }
                    });

                    return resultData;
                }
            },
            recordAdded: function(event, data) {
                RefreshPage();
            },
            recordDeleted: function(event, data) {
                //RefreshPage();
            },
            fields: {
                AddressID: {
                    key: true,
                    create: false,
                    edit: false,
                    list: true
                },
                AddressLine1: {
                    title: 'AddressLine1',
                    width: '20%'
                },
                AddressLine2: {
                    title: 'AddressLine2',
                    create: true,
                    edit: true,
                    width: '20%'
                },
                City: {
                    title: 'City',
                    create: true,
                    edit: true,
                    width: '15%'
                },
                StateProvinceID: {
                    title: 'StateProvinceID',
                    create: false,
                    edit: false,
                    width: '10%'
                },
                PostalCode: {
                    title: 'PostalCode',
                    create: true,
                    edit: true,
                    width: '10%'
                },
                ModifiedDate: {
                    title: 'ModifiedDate',
                    edit: false,
                    create: false,
                    width: '15%',
                    display: function (data) { return moment(data.record.ModifiedDate).format('DD/MM/YYYY HH:mm:ss'); }
                }
            }
        });

        $(document).ready(function() {
            var updateResults = [];
            $("input#autocomplete").autocomplete({
                source: function(request, response) {
                    $.ajax({
                        url: "http://localhost:49908/Search/search",
                        dataType: "json",
                        data: {
                            term: request.term,
                        },
                        success: function(data) {
                            var itemArray = new Array();
                            for (i = 0; i < data.length; i++) {
                                var labelData = data[i].Name + ", " + data[i].StateProvinceCode + ", " + data[i].CountryRegionCode;
                                itemArray[i] = { label: labelData, value: labelData, data: data[i] }
                            }

                            console.log(itemArray);
                            response(itemArray);
                        },
                        error: function(data, type) {
                            console.log(type);
                        }
                    });
                },
                select: function(event, ui) {
                    $("#selectedstateprovinceid").val(ui.item.data.StateProvinceID);
                    $('#addressResultsForStateProvince').jtable('load', {selectedstateprovinceid : ui.item.data.StateProvinceID});
                    console.log(ui.item);
                }
            });
        });
    </script>
}           

应用程序如下所示:
这里写图片描述

结论

现在该应用程序具有超强大的功能,用于搜索的Elasticsearch的高性能以及MS SQL Server中CUD操作的交易。 这对于具有大量数据的MVC应用来说是一个很好的解决方案。Elasticsearch与其他搜索引擎不谋而合。

横空出世、MyBatis-Plus同款ES ORM框架,用起来够优雅 Easy-Es(简称EE)是一款基于Elasticsearch(简称ES)官方提供的RestHighLevelClient打造的ORM开发框架,在RestHighLevelClient的基础上,只做增强不做改变,为简化开发、提高效率而生。EE和Mybatis-Plus(简称MP)的用法非常相似,如果你之前使用过MP的话,应该能很快上手EE。EE的理念是:把简单、易用、方便留给用户,把复杂留给框架。EE的主要特性如下:全自动索引托管:开发者无需关心索引的创建、更新及数据迁移等繁琐步骤,框架能自动完成。 阅读详情

相关推荐

小程序HTTPS证书配置踩坑记:为什么Android访问失败而iOS正常?

本文深入剖析了小程序开发中常见的跨平台网络问题:Android访问HTTPS接口失败而iOS正常。核心原因在于服务器(如Nginx)HTTPS证书链配置不完整,Android系统对此校验严格,而iOS相对宽松。文章提供了从问题诊断、使用在线工具检测到修复Nginx证书链配置的完整解决方案,并总结了HTTPS部署的最佳实践,帮助开发者从根本上避免此类“玄学”故障。

weixin_29207149的博客 393

ElasticsearchRestTemplate 和ElasticsearchRepository 的使用

ElasticsearchRestTemplate 和ElasticSearchClient 的使用

深圳市多克创新科技有限公司 1万+

三部对接 sora-2:OpenAI 最新视频模型快速接入指南

本文介绍OpenAI最新视频生成模型Sora-2的接入方案,重点解析其Chat格式调用功能。开发者可通过在提示词中嵌入"横屏/竖屏""时长""清晰度"等要求快速生成视频。文章分三部分:1)基础准备(环境配置与API密钥获取);2)核心调用(提供Python/Java示例代码);3)结果查询与优化建议。Sora-2支持多语言调用,简化了视频生成流程,适用于短视频、广告创意等场景。

2501_93565190的博客 3422

5个 elasticsearch实战应用案例和详细分析

bash代码解读复制代码。

2401_87704405的博客 3218

深入解析LVDS电平标准在LCD屏接口设计中的关键作用

本文深入解析了LVDS电平标准在LCD屏接口设计中的核心作用。文章不仅阐释了LVDS低电压差分信号的工作原理、关键电气参数及抗噪优势,还详细对比了VESA与JEIDA两种主流数据格式,并提供了从PCB布局布线到信号调试的实战避坑指南,是确保高速、稳定显示的关键技术参考。

weixin_28419039的博客 333

[ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429

[ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429 可以使用一些编码字符来制作URI,以访问WEB-INF目录的内容和/或绕过一些安全限制。默认合规模式允许带有包含 %u002e 段的 URI 的请求访问WEB-INF目录中的受保护资源。

qq_51577576的博客 3207

Elastic实战:通过spring data elasticsearch实现索引的CRUD;实现mysql全量/增量同步到ES

0. 引言 elasticsearch官方的java客户端有tranport client,rest high level client,但进行索引的增删改查的操作不够简便。因此我们引入spring data elasticsearch来实现索引的CRUD 1. 版本对应关系 在引入spring data之前要先了解版本之间的对应关系,这个我们可以在spring data 官方文档中查询到 这里我的es用的7.14.0版本,所以需要引入spring data elasticsearch4.3.x版本的依赖

55555的博客 2754

在 SAP 中,寄售业务(Consignment)与管道业务(Pipeline)都属于“物料先到、发票后到”的特殊采购模式,但两者的库存形态、物权转移时点、结算触发条件、系统配置完全不同

SAP中寄售业务与管道业务均属"先货后票"采购模式,但存在本质差异。寄售业务(如手机芯片)采用实物库存管理(标记"K"),物权在领用时转移,通过411K/201K移动类型触发负债;管道业务(如蒸汽)无实物库存,采用261P等移动类型直接消耗并生成应付。系统配置上,寄售需K类信息记录及GR收货,管道需P类信息记录且免GR。两者均通过MRKO汇总结算,但寄售按领用量计费,管道按提取量实时计费。核心区别在于库存形态与物权转移时点。

金牌架构师 554

Easy-Es框架实践测试整理 基于ElasticSearch的ORM框架

Easy-Es(简称EE)是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架,在 RestHighLevelClient 的基础上,只做增强不做改变,为简化开发、提高效率而生。EE是Mybatis-Plus的Es平替版,在有些方面甚至比MP更简单,同时也融入了更多Es独有的功能,助力您快速实现各种场景的开发.

发现问题,面对问题,分析问题,解决问题,总结问题 4067

063、推挽变换器的磁偏问题与解决

本文针对推挽变换器中的磁偏问题展开分析。作者通过实际案例指出,磁偏主要由开关管导通压降差异和驱动信号不对称引起,会导致变压器饱和、MOS管炸毁等问题。文章提供了四种解决方案:采用电流模式控制、添加隔直电容、优化对称驱动设计以及引入磁芯气隙(作为最后手段)。调试时应重点观察原边电流波形对称性、变压器声音和直流分量。作者强调实践经验的重要性,建议预留隔直电容位置,并指出推挽拓扑在500W以上功率场合的局限性。这些基于实战的经验总结为电源工程师提供了有价值的参考。

Jack010169的博客 310

Android 13.0 设置默认屏幕亮度百分比

在13.0的系统ROM产品开发中,在一些产品开发中,对于设置默认屏幕亮度和屏幕亮度百分比的功能,在开发中也是常见的功能,在10.0的平台设置可能有一些不同,一般的都是在SettingProvider中设置就可以了 在11.0以后的系统中设置默认屏幕亮度的方法就不同了,接下来具体分析功能的实现

安卓兼职framework和app工程师的博客 1560

ElasticsearchCRUD翻译系列之(一): ElasticsearchCRUD 介绍

ELASTICSEARCH CRUD .NETPROVIDER 翻译自(原文地址: https://damienbod.com/2014/09/22/elasticsearch-crud-net-provider/) 本文介绍了ElasticsearchCRUD NuGet包的使用。ElasticsearchCRUD便于你通过对实体的插入、删除、修改从Elasticsearch中查找单个记录...

weixin_30284355的博客 66

详解【计算机类&面试真题】军队文职考试——第7期:C盘格式化需要注意什么?| 两台笔记本连起来后ping不同,可能存在哪些问题?| 模拟信号到数字信号是如何转化的?| 计算机由哪些部件组成?

这是我分享的系列面试知识——军队文职(计算机类)面试真题详解(第7期)。本期分享:两台笔记本连起来后ping不同,你觉得可能存在哪些问题?模拟信号到数字信号是如何转化的?谈一谈计算机由哪些部件组成?如何加强计算机网络安全管理?若通过域名无法访问,而通过IP地址能访问。这是怎么回事?你将如何解决?谈一谈C盘格式化需要注意什么?开放类题目:如果应聘的岗位和你想的差距很远,你怎么办?

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 1917

Elasticsearch的使用场景深入详解

Elasticsearch 是一个功能强大、应用广泛的开源搜索和分析引擎。它可以用于各种场景,例如全文搜索、日志分析、运维监控、安全分析、数据分析等等。

铭渊老黄 2282

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

浅谈Elasticsearch和实际应用

PacificA是一个读写都满足强一致性的算法,它把数据的一致性与配置的一致性分开,使用额外的一致性组件(Configuration Manager)维护配置的一致性,**在数据的可用副本数少于半数时,仍可以写入新数据并保证强一致性。拉取主分片的translog:在副分片恢复期间允许新的写操作,从复制Lucene分段的那一刻开始,所恢复的副分片数据不包括新增的内容,而这些内容存在于主分片的translog中,因此副分片需要从主分片节点拉取translog进行重放,以获取新增内容。分片副本使用主从模式。

lingboo111的博客 1009

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ES既是搜索引擎又是数据库?真的有那么全能吗?

作者介绍李猛(ynuosoft),Elastic-stack产品深度用户,ES认证工程师,2012年接触Elasticsearch,对Elastic-Stack开发、架构、运维等方面有深...

过往记忆大数据 1761

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

ElasticsearchCRUD使用(四)【使用EF从SQLServer到Elasticsearch的数据传输】

AdventureWorks2012用作数据库,可以在这里下载。 您需要在代码工作之前安装数据库。应用程序创建一个新的控制台应用程序,并从NuGet下载ElasticsearchCRUD和Entity Framework。 从AdventureWorks数据库创建代码第一个数据库。向项目添加一个新项,选择ADO.NET实体数据模型: 现在从数据库选项首先选择代码。 数据库已经存在。 从

极客神殿 3511

Elasticsearch的几种架构(ELK,EL,EF)性能对比测试报告

Elasticsearch的几种架构(ELK,EL,EF)性能对比测试报告 Elasticsearch的几种架构性能对比测试报告 1.前言 选定了Elasticsearch作为存储的数据库,但是还需要对Elasticsearch的基础架构做一定测试,所以,将研究测试报告输出如下。 2.日志系统架构的基础 2.1所需环境和依赖软件 1)...

weixin_30664051的博客 807

Elasticsearch应用详解,看这一篇就够了,包教包会!(转)

Elasticsearch搞监控得益于其提供的Elastic Stack产品生态,丰富完善,很多时候监控需要立体化,除了指标之外,还需要有各种日志的采集分析,如果用其它纯指标监控产品,如Promethues,遇到有日志分析的需求,还必须使用Elasticsearch,这对于技术栈来说,又扩增了,相应的掌控能力会下降,个人精力有限,无法同时掌握很多种数据产品,如此选择一个更加通用的产品才符合现实。大数据领域的需求会让你对于查询与聚合特别关注,海量的数据需要快速的检索,也需要快速的聚合结果。

678

Elasticsearch扫盲篇

在日常的工作和学习中,当我们说想找查询任何的信息的时候,可能第一时间会想到上百度或者谷歌去搜索一下。比如说找一部自己喜欢的电影,或者说找一本喜欢的书,或者找一条感兴趣的新闻。但是百度和谷歌不等于搜索,他们只是我们搜索时使用的工具。搜索,就是在任何场景下,查找你想要的信息。这个时候需要输入一段你要搜索的关键字,然后就期望找到这个关键字相关的信息。ElasticSearch是一款非常强大的、基于Lucene的开源搜索及分析引擎;它是一个实时的分布式搜索分析引擎,它能让你以前所未有的速度和规模,去探索你的数据。

愿万事胜意 1万+

高性能elasticsearch ORM开发库使用介绍

为什么80%的码农都做不了架构师?>>> ...

weixin_33709219的博客 1192

es向量检索里的efSearchc参数是干嘛用的

ef_search是HNSW算法在查询阶段的精度控制器低值→ 速度优先,适合简单过滤场景(如实时日志分析);高值→ 精度优先,保障语义搜索/推荐系统效果。需结合数据规模、分片策略及硬件资源动态调整。

仅做个人笔记 746

elasticsearch实战应用

Elasticsearch作为一个分布式、实时全文搜索引擎,在实战应用中展现出了强大的搜索和分析能力。通过合理的安装与配置、性能优化、集群管理以及与Logstash和Kibana的集成,可以充分发挥Elasticsearch的优势,为企业和开发者提供高效、可靠的数据处理解决方案。同时,随着技术的不断发展和应用场景的不断拓展,Elasticsearch将继续为企业和开发者带来更多的价值和创新。

jun778895的博客 1450

elasticsearch介绍与快速应用

我们选择最新操作elasticsearch方法,通过java api client 操作java 8 或者更新版本elasticsearch版本7.17支持jackson 或者JSON-B库。

Jelly 570
上一篇: ElasticsearchCRUD使用(五)【Elasticsearch中的子文档,父文档】
下一篇: ElasticsearchCRUD使用(七)【Elasticsearch中的实时重建索引】
.NET跨平台
博客等级 码龄15年 6066粉丝 738原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值