产品搜索算法最佳实践

时间:2015-03-15 12:22:01

标签: c# algorithm backend

我关注根据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"
    });
}

请看我讨厌这种代码

1 个答案:

答案 0 :(得分:1)

您可以使用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()扩展名。