2012-06-08 69 views
1

好吧,我在這裏的一個樹樁上。即使代碼拼錯,也要搜索產品

基本上我遇到的問題是,當人們在尋找某些東西時,他們會誤以爲很多時候涉及多個0的代碼,例如當搜索時:K00000WEFLZ他們誤認爲0,然後產品結果沒有任何東西返回,我基本上是想試一試,以便搜索檢查在字母「K」之後搜索是否包含一定數量的0(因爲K總是會有10+的ID號碼, 5 0),如果它在搜索操作中用「*」代替它,仍然可以讓你找到產品,無論他們輸入問題多麼錯誤。

我知道我將不得不做一個自定義的類,並覆蓋默認的這個(但很多這是不能訪問/是私人)作爲默認的搜索模式不能改變,因爲這會改變它爲每個人,我只希望它爲這個特定的網站。

我也不能在開頭或結尾使用通配符,因爲它會爲許多結果匹配英里,因爲它有一個巨大的目錄。

據我知道這是處理與類默認邏輯搜索代碼:

protected virtual IList<Product> CreateCustomCollection() 
{ 
     var list = new List<Product>(); 

     switch (mode) 
     { 
      case ProductRepeaterMode.Search: 

       if (Page.Request.QueryString["search"] != null && Page.Request.QueryString["search"].Length != 0) 
       { 
        bool[] customString = new bool[5] { SearchCustomString1, SearchCustomString2, SearchCustomString3, SearchCustomString4, SearchCustomString5 }; 
        IList<Product> results = Fabric.ObjectProvider.Get<IProductSearchCommand>().Search(Page.Request.QueryString["search"], out searchWords, IncludeSkus, IsPublicFacing, customString, CoreHttpModule.Session); 

        var retailOrder = WebStoreManager.CurrentOrder as IRetailOrder; 
        var accountOrder = WebStoreManager.CurrentOrder as IAccountOrder; 

        IList<Product> productsToRemove = new List<Product>(); 
        IList<Product> productsToAdd = new List<Product>(); 

        foreach (var product in results) 
        { 
         if (hideRestrictedProducts) 
         { 
          if (retailOrder != null) 
          { 
           if (!product.CanBePurchasedByRetailCustomer || product.AgentOnly) 
            productsToRemove.Add(product); 
          } 
          else 
          { 
           if (accountOrder != null) 
           { 
            var add = false; 

            if (product.CanBePurchasedOnAccount) 
             add = true; 

            if (product.AgentOnly) 
            { 
             if (accountOrder.Agent != null) 
              add = true; 
             else 
              add = false; 
            } 

            if (!add) 
             productsToRemove.Add(product); 
           } 
          } 
         } 

         // Replace SKUs with lines 
         if (resolveSkusToLines) 
         { 
          var sku = product.Role as SkuProductRole; 
          if (sku != null) 
          { 
           productsToRemove.Add(product); 
           if (sku.Owner != null && sku.Owner.Product != null) 
           { 
            var line = sku.Owner.Product; 
            if (!results.Contains(line) && !productsToAdd.Contains(line)) 
             productsToAdd.Add(line); 
           } 
          } 
         } 
        } 

        foreach (Product product in productsToAdd) 
        { 
         results.Add(product); 
        } 

        foreach (Product product in productsToRemove) 
        { 
         results.Remove(product); 
        } 

        foreach (var result in results) 
         list.Add(result); 
       } 
       break; 
     } 
     return list; 
    } 
+0

我正在考慮可能分手的搜索字符串轉換成字符數組,然後檢查最相似的字符串的字符數組的數據庫,但是我覺得這種做法是非常低效的 –

+0

我還可以使它這樣如果有說... 2+ 0的我把它們全部換成通配符。 –

+0

我正在研究使用正則表達式來檢測並替換它 –

回答

2

模糊邏輯,總得愛它。我會這樣做,這並沒有說明它應該如何完成,但我會給自己最好的嘗試,就是從搜索字符串本身構建一個正則表達式。

對待正則生成的壓縮操作的正則表達式生成器。從你的字符數組開始,並從中建立正則表達式搜索,每當你在一行中找到2個相同的字符,用'+'字符替換第二個(並忽略其他字符),然後使用正則表達式運行結果搜索而不是精確的字符串匹配。

K00000WEFLZ會變成K0+WEFLEZ,並匹配K,1個或多個0的WEFLEZ。該算法需要爲任何重複的字符執行此操作,因此可能會使其變得有點愚蠢。像KK000WWLEFF22就會來K+0+W+LEF+2+。沒有那麼好的搜索字符串,並可能匹配很多你不想要的東西......但是很有效。或者你可以限制它只能取代0或0。等等......無論結果如何,最好的工作。

另一種方式,我會推薦它將實時過濾。但是它的實用性更依賴於預期的正常功能。用戶輸入值是否更常見,或者更常見是從其他地方複製/粘貼。在第二種情況下,實時過濾完全沒用。否則...重新過濾每個keyPress或TextChanged事件的列表。至少這樣他們可能會在整個列表消失的想法,因爲進入了一個額外的0.1

編輯 - 添加代碼示例

private string RegStringZipper(string searchString) 
    { 
     StringBuilder sb = new StringBuilder(); 
     char lastChar = new char(); 
     bool plusFlag = false; 
     foreach (char c in searchString) 
     { 
      if (sb.Length == 0) 
      { 
       sb.Append(c); 
       lastChar = c; 
      } 
      else 
      { 
       if (lastChar == c) 
       {//we have a repeating character 
        //Note: Here is also where if you only wanted to filter a specific character, like 0, you would check for it. 
        if (!plusFlag) 
        {//we have not already added the + 
         sb.Append('+'); 
         plusFlag = true; 
        } 
        //else do nothing, skip the characer 
       } 
       else 
       { 
        sb.Append(c); 
        plusFlag = false; 
        lastChar = c; 
       } 
      } 
     } 
     return sb.ToString(); 
    } 

爲在那裏我會適應它到你的代碼。 ..這實際上取決於搜索功能的實際工作方式,它不是我以前玩過的東西......說到......如果它起作用,它看起來可能會起作用,交易出'+'爲'*'在上面的代碼....

if (Page.Request.QueryString["search"] != null && Page.Request.QueryString["search"].Length != 0) 
      { 
       bool[] customString = new bool[5] { SearchCustomString1, SearchCustomString2, SearchCustomString3, SearchCustomString4, SearchCustomString5 }; 
       string SearchString = RegStringZipper(Page.Request.QueryString["search"]); 
       //please note, given that I dont know what FabricProvider.Search works on, I dont actually know that this works as intended. 
       IList<Product> results = Fabric.ObjectProvider.Get<IProductSearchCommand>().Search(SearchString, out searchWords, IncludeSkus, IsPublicFacing, customString, CoreHttpModule.Session); 
+1

有趣的問題跟進:任何建議如何如果有多個匹配項(即相關性分數),可能會對RegEx結果進行排序? – nicholas

+0

你知道嗎....我不知道。也許比較原始搜索字符串與提供的結果的字符串長度......但是如果這些是產品ID,則邏輯表示它們可能都將是相同的長度。獲得'相關性'會非常複雜。任何人都有一個想法,我想實際聽到它。 – Nevyn

+0

這是解決方案。你想匹配一個模式。正則表達式建立在模糊邏輯之上。 –