产品搜索算法最佳实践

Product Search Algorithm Best practice

我担心根据 UI 选择进行搜索。例如,我将搜索具有许多参数的产品我的代码看起来像那样

if(param1 != null && param1 == 1 && param2 != null && param2 == 2 && param3 != null && paaram3 == 3)
{
}
else if(param1 != null && param1 == 1 && param2 != null && param2 == 2)
{
}
else if(param1 != null && param1 == 1)

应该有最好的方法,因为有很多可能性,比如 polinom。

应该有一个方法谓词等。我不想写这样的代码

public ActionResult SearchProductVehicle(string CatagoryId, string MarkId, string ModelId, string HomeCat6,
    string productFuelType, string productCaseType, string productGearType, string fader1, string fader2, string fader3, string fader4, string startPrice, string endPrice,
string hdnInpSearch)
{
    if (CatagoryId == "-1")
    {
        List<Product> prdcs = Session["BeforeProducts"] as List<Product>;
        return View(new HomeViewModel
        {
            listpG = context.ProductGroups.ToList(),
            listCatG = context.Categories.ToList(),
            listMarks = context.Marks.ToList(),
            currencies = context.Currencies.ToList(),
            products = prdcs,
            cities = context.Cities.ToList(),
            listFuelTypes = context.FuelTypes.ToList(),
            listCaseTypes = context.CaseTypes.ToList(),
            listGearTypes = context.GearTypes.ToList()
        });
    }

    var products = new List<Product>();

    if (hdnInpSearch == null)
    {
        hdnInpSearch = string.Empty;
    }
    hdnInpSearch = hdnInpSearch.TrimStart().TrimEnd();
    if (hdnInpSearch == "Parça kodu, adı ya da açıklamasında" || hdnInpSearch == "İlan başlığı ya da açıklamasında" || hdnInpSearch == "Hizmet adı ya da açıklamasında")
    {
        hdnInpSearch = string.Empty;
    }

    var criteria = hdnInpSearch.Split(' ');

    var qry = string.Empty;

    // paged query should be ignore the other parameters
    if (Request.QueryString["page"] != null && Convert.ToInt32(Request.QueryString["page"]) > 1)
    {
        CatagoryId = "";
        MarkId = "null";
        ModelId = "null";
        HomeCat6 = "null";
    }

    if (HomeCat6 == null)
    {
        qry = HttpContext.Request.Url.AbsoluteUri + "?CatagoryId=" + CatagoryId + "&MarkId=" + MarkId + "&ModelId=" + ModelId + "&HomeCat6=" + HomeCat6 + "&hdnInpSearch=" + hdnInpSearch;
        Int32.TryParse(MarkId, out marId);
        //var marId = Convert.ToInt32(MarkId);
        var fChilds = context.Categories.Where(k => k.Id == marId).Select(m => m.Id).ToList();


        foreach (object obj in fChilds)
            types1.Add(Convert.ToInt32(obj));

        var sChilds = context.Categories.Where(k => types1.Contains(k.ParentId)).Select(m => m.Id).ToList();

        foreach (object obj in sChilds)
            types2.Add(Convert.ToInt32(obj));

        var tChilds = context.Categories.Where(k => types2.Contains(k.ParentId)).Select(m => m.Id).ToList();

        foreach (object obj in tChilds)
            types3.Add(Convert.ToInt32(obj));

        types3.Add(marId);
        crit = criteria[0].ToString();
        products = context.Products.Where(K => K.ProductType == 1 && K.IsActive == true && types3.Contains(K.CategoryId) && (K.Name.Contains(crit) || crit == string.Empty || crit == string.Empty)).Take(500).ToList();
    }
    else
    {
        if (CatagoryId != "null" && MarkId != "null" && ModelId != "null" && HomeCat6 != "null")
        {
            Debug.Assert(HttpContext.Request.Url != null, "HttpContext.Request.Url != null");
            qry = HttpContext.Request.Url.AbsoluteUri + "?CatagoryId=" + CatagoryId + "&MarkId=" + MarkId + "&ModelId=" + ModelId + "&HomeCat6=" + HomeCat6 + "&hdnInpSearch=" + hdnInpSearch;
            var subModId = Convert.ToInt32(HomeCat6);
            var fChilds = context.Categories.Where(k => k.Id == subModId).Select(m => m.Id).ToList();
            var types1 = fChilds.Select(fc => (int?)fc).ToList();
            var crit = criteria[0].ToString();
            products = context.Products.Where(K => K.ProductType == 1 && K.IsActive == true && types1.Contains(K.CategoryId) && (K.Name.Contains(crit) || crit == string.Empty)).Take(500).ToList();
        }
        else
        {
            if (CatagoryId != "null" && MarkId != "null" && ModelId != "null")
            {
                qry = HttpContext.Request.Url.AbsoluteUri + "?CatagoryId=" + CatagoryId + "&MarkId=" + MarkId + "&ModelId=" + ModelId + "&HomeCat6=" + HomeCat6 + "&hdnInpSearch=" + hdnInpSearch;
                var modId = Convert.ToInt32(ModelId);
                var fChilds = context.Categories.Where(k => k.Id == modId).Select(m => m.Id).ToList();
                var types1 = fChilds.Select(fc => (int?)fc).ToList();

                var sChilds = context.Categories.Where(k => types1.Contains(k.ParentId)).Select(m => m.Id).ToList();
                var types2 = sChilds.Select(sc => (int?)sc).ToList();
                types2.Add(modId);
                var crit = criteria[0].ToString();
                products = context.Products.Where(K => K.ProductType == 1 && K.IsActive == true && types2.Contains(K.CategoryId) && (K.Name.Contains(crit) || crit == string.Empty)).Take(500).ToList();
            }
            else
            {
                if (CatagoryId != "null" && MarkId != "null" && HomeCat6 == "null")
                {
                    qry = HttpContext.Request.Url.AbsoluteUri + "?CatagoryId=" + CatagoryId + "&MarkId=" + MarkId + "&ModelId=" + ModelId + "&HomeCat6=" + HomeCat6 + "&hdnInpSearch=" + hdnInpSearch;
                    Int32.TryParse(MarkId, out marId);
                    //var marId = Convert.ToInt32(MarkId);
                    var fChilds = context.Categories.Where(k => k.Id == marId).Select(m => m.Id).ToList();


                    foreach (object obj in fChilds)
                        types1.Add(Convert.ToInt32(obj));

                    var sChilds = context.Categories.Where(k => types1.Contains(k.ParentId)).Select(m => m.Id).ToList();

                    foreach (object obj in sChilds)
                        types2.Add(Convert.ToInt32(obj));

                    var tChilds = context.Categories.Where(k => types2.Contains(k.ParentId)).Select(m => m.Id).ToList();

                    foreach (object obj in tChilds)
                        types3.Add(Convert.ToInt32(obj));

                    types3.Add(marId);
                    crit = criteria[0].ToString();
                    products = context.Products.Where(K => K.ProductType == 1 && K.IsActive == true && types3.Contains(K.CategoryId) && (K.Name.Contains(crit) || crit == string.Empty || crit == string.Empty)).Take(500).ToList();
                }
                else
                {
                    if (CatagoryId != "null" && MarkId == "null" && ModelId == "null" && HomeCat6 == "null")
                    {
                        qry = HttpContext.Request.Url.AbsoluteUri + "?CatagoryId=" + CatagoryId + "&MarkId=" + MarkId + "&ModelId=" + ModelId + "&HomeCat6=" + HomeCat6 + "&hdnInpSearch=" + hdnInpSearch;
                        var crit = criteria[0].ToString();
                        products = context.Products.Where(K => K.ProductType == 1 && K.IsActive == true && (K.Name.Contains(crit) || crit == string.Empty)).Take(500).ToList();
                    }
                    else
                    {
                        if (CatagoryId == "null" && MarkId == "null" && ModelId == "null" && HomeCat6 == "null")
                        {
                            qry = HttpContext.Request.Url.AbsoluteUri + "?CatagoryId=" + CatagoryId + "&hdnInpSearch=" + hdnInpSearch;

                            if (criteria[0] != string.Empty)
                            {
                                var tempPro1 = new List<Product>();

                                foreach (var sCriteria in criteria)
                                {
                                    var criteria1 = sCriteria;
                                    tempPro1.AddRange(context.Products.Where(k => k.ProductType == 1 && k.IsActive == true && k.Name.Contains(criteria1)).ToList());
                                    tempPro1.AddRange(context.Products.Where(k => k.ProductType == 1 && k.IsActive == true && k.Explanation.Contains(sCriteria)).ToList());
                                }
                                products = tempPro1.OrderByDescending(m => m.RecordDate).Take(500).ToList();
                            }
                        }
                    }
                }
            }
        }
    }

    if (!HttpContext.Request.UrlReferrer.AbsoluteUri.Contains("SearchProduct"))
    {
        HttpContext.Session["qry"] = qry;
    }
    if (HttpContext.Request.UrlReferrer.AbsoluteUri.Contains("GeneralSearch"))
    {
        HttpContext.Session["qry"] = HttpContext.Request.UrlReferrer.AbsoluteUri;
    }
    else
    {
    }

    if (!products.Any() && CatagoryId == "null" && MarkId == "null" && ModelId == "null" && HomeCat6 == "null")
    {
        products = context.Products.Where(k => k.ProductType == 1 && k.IsActive == true).OrderByDescending(m => m.Id).Take(100).ToList();
    }

    if (productFuelType != null)
    {

        if (productFuelType.Trim() != "1")
        {
            var fuelType = Convert.ToInt32(productFuelType);
            products = products.Where(k => k.FuelType == fuelType).ToList();
        }
        if (productCaseType.Trim() != "1")
        {
            var caseType = Convert.ToInt32(productCaseType);
            products = products.Where(k => k.CaseType == caseType).ToList();
        }
        if (productGearType.Trim() != "1")
        {
            var gearType = Convert.ToInt32(productGearType);
            products = products.Where(k => k.GearType == gearType).ToList();
        }

        if (fader1.Trim() != "1960")
        {
            var modelYearStart = Convert.ToInt32(fader1);
            products = products.Where(k => Convert.ToInt32(k.ModelYear) >= modelYearStart).ToList();
        }
        if (fader2.Trim() != "2015")
        {
            var modelYearEnd = Convert.ToInt32(fader2);
            products = products.Where(k => Convert.ToInt32(k.ModelYear) <= modelYearEnd).ToList();
        }

        if (fader3.Trim() != "750")
        {
            var engineStart = Convert.ToInt32(fader3);
            products = products.Where(k => k.EngineCapacity >= engineStart).ToList();
        }
        if (fader4.Trim() != "10000")
        {
            var engineEnd = Convert.ToInt32(fader4);
            products = products.Where(k => k.EngineCapacity <= engineEnd).ToList();
        }

        if (startPrice.Trim() != string.Empty)
        {
            var priceStart = Convert.ToInt32(startPrice);
            products = products.Where(k => k.CurrentPrice >= priceStart).ToList();
        }
        if (endPrice != null && endPrice.Trim() != string.Empty)
        {
            var priceEnd = Convert.ToInt32(endPrice);
            products = products.Where(k => k.CurrentPrice <= priceEnd).ToList();
        }
    }

    List<Product> lpd2 = products.Take(3).ToList();
    string exp = "";
    foreach (Product p in lpd2)
        exp += p.Name + ", " + p.Code;

    if (products.Count > 0)
    {
        ViewBag.Title = exp;
        Category catt = null;
        string catname = "";
        if (products[0].CategoryId != null)
        {
            Int32 cidd = Convert.ToInt32(products[0].CategoryId);
            catt = context.Categories.Where(k => k.Id == cidd).FirstOrDefault();
            catname = catt.Name;
        }
        ViewBag.Description = catname + "/" + products[0].Name;
        City city = null;
        string cityName = "";
        if (products[0].City != null)
        {
            Int32 cityidd = Convert.ToInt32(products[0].City);
            city = context.Cities.FirstOrDefault(k => k.Id == cityidd);
            cityName = city.Name;
        }

        if (city != null)
            cityName = city.Name + ",";
        ViewBag.Keywords = cityName + catname + "," + exp;
    }

    Session["BeforeProducts"] = products;
    List<Product> prods = products.OrderByDescending(m => m.Id).ToList();

    return View(new HomeViewModel
    {
        listpG = context.ProductGroups.ToList(),
        listCatG = context.Categories.ToList(),
        listMarks = context.Marks.ToList(),
        currencies = context.Currencies.ToList(),
        products = prods,
        cities = context.Cities.ToList(),
        listFuelTypes = context.FuelTypes.ToList(),
        listCaseTypes = context.CaseTypes.ToList(),
        listGearTypes = context.GearTypes.ToList(),
        ViewType = "VhicleProduct"
    });
}

请看我讨厌这种代码

您可以使用 PredicateBuilder 来形成复杂的查询。

喜欢,

        var predicate = PredicateBuilder.False<Product>();

        if (param1 != null && param1 == 1 && param2 != null && param2 == 2 && param3 != null && paaram3 == 3)
        {
            predicate = predicate.Or(p => p.param1 == param1 && p.param2 == param1 = 2 && p.param3 == param3);
        }
        else if (param1 != null && param1 == 1 && param2 != null && param2 == 2)
        {
          ---------
        }
        else if (param1 != null && param1 == 1)
          ---------

最后,

        dbContextContext.Products.AsExpandable().Where(predicate);

还有一个 Universal PredicateBuilder 也可用,它不需要 LinqPadAsExpandable() 扩展名。