v4.40 Help needed trying to modify searchProducts

1 year ago
Hi, i'm new to dotnet and i'm having an error trying to modify ProductService.cs SearchProductAsync:

                productsByKeywords =
                        from p in _productRepository.Table
                        where p.Name.Contains(keywords) ||
                            (searchDescriptions &&
                                (p.ShortDescription.Contains(keywords) || p.FullDescription.Contains(keywords))) ||
                            (searchManufacturerPartNumber && p.ManufacturerPartNumber == keywords) ||
                            (searchSku && p.Sku.Contains(keywords))
                        select p.Id;

I need to split keywords in words (string list) and p.Name should contain all the words in keywords

i.e.
keywords = "shirt blue"
p.name = "this shirt is very blue" should match

I'm having an error LinqException: Sequence 'value(Nop.Services.Catalog.ProductService+<>c__DisplayClass55_1).keywordsList' cannot be converted to SQL.

                IQueryable<int> productsByKeywords;
                List<string> keywordsList = keywords.Split(',').ToList();
                productsByKeywords =
                        from p in _productRepository.Table
                        where keywordsList.All(aname => p.Name.Contains(aname)) ||
                            (searchDescriptions &&
                                (p.ShortDescription.Contains(keywords) || p.FullDescription.Contains(keywords))) ||
                            (searchManufacturerPartNumber && p.ManufacturerPartNumber == keywords) ||
                            (searchSku && p.Sku.Contains(keywords))
                        select p.Id;

Thank you
1 year ago
This might help you,
private IQueryable<int> ExclusiveKeyWordSearch(string keywords)
        {
            var products = _productRepository.Table;
            var searchstrings = keywords.Split(null).Select(x => x.ToLower()).ToArray();

            foreach (string q in searchstrings)
            {
                products = products.Where(p => p.Name.ToLower().Contains(q));
            }

            return products.Select(p=> p.Id);
        }

On product service:
productsByKeywords = productsByKeywords.Union(ExclusiveKeyWordSearch(keywords));

I know this is not optimized solution but it's linq2db limitation and that's the way I found.
From, https://stackoverflow.com/questions/2369022/using-contains-in-linq-to-sql
1 year ago
Additional Note on my solution, keep existing keywords search as it is, just add this function as an addition to add.
IQueryable<int> productsByKeywords;

                productsByKeywords =
                        from p in _productRepository.Table
                        where p.Name.Contains(keywords) ||
                            (searchDescriptions &&
                                (p.ShortDescription.Contains(keywords) || p.FullDescription.Contains(keywords))) ||
                            (searchManufacturerPartNumber && p.ManufacturerPartNumber == keywords) ||
                            (searchSku && p.Sku == keywords)
                        select p.Id;

               productsByKeywords = productsByKeywords.Union(ExclusiveKeyWordSearch(keywords));

And, this is the outcome.
1 year ago
Thank you very much, Mahbubur.
7 months ago
hi, since the full text search its not a feature anymore im trying to follow ur suggestoion but im doing something wrong:

in productservice.cs i have added your code here:
in line 845
            if (!string.IsNullOrEmpty(keywords))
            {
                var langs = await _languageService.GetAllLanguagesAsync(showHidden: true);

//code added
  IQueryable<int> ExclusiveKeyWordSearch(string keywords)
                {
                    var products = _productRepository.Table;
                    var searchstrings = keywords.Split(null).Select(x => x.ToLower()).ToArray();

                    foreach (string q in searchstrings)
                    {
                        products = products.Where(p => p.Name.ToLower().Contains(q));
                    }

                    return products.Select(p => p.Id);
                }
//end


then i have modifyed the following (bold is what it has been added)
IQueryable<int> productsByKeywords;

                productsByKeywords =
                        from p in _productRepository.Table
                        where p.Name.Contains(keywords) ||
                            (searchDescriptions &&
                                (p.ShortDescription.Contains(keywords) || p.FullDescription.Contains(keywords))) ||
                            (searchManufacturerPartNumber && p.ManufacturerPartNumber == keywords) ||
                            (searchSku && p.Sku == keywords)
                        select p.Id;

                productsByKeywords = productsByKeywords.Union(ExclusiveKeyWordSearch(keywords));


then i rebuilt the solution and pubblished nop.web, but  it seems that it doesnt work

for example i have a product name "PRIMORDIAL GATTO SALMONE E TONNO GRAIN FREE"

if i search like "PRIMORDIAL GATTO" it works, but if i search something like "PRIMORDIAL TONNO" id doesnt work

what im i doing wrong?

Sorry but im still new to dot.net
Thx
7 months ago
noffy wrote:
hi, since the full text search its not a feature anymore im trying to follow ur suggestoion but im doing something wrong:

please first modify default nopCommerce project  of your version and run from visual studio and check again. full text search will be implemented soon. here is the discussion of it https://github.com/nopSolutions/nopCommerce/issues/6058
6 months ago
hi,
i followded your instructions and the search works fine but only in the dropdown search near the "search" button.
it drops down all the options based and what i write, but when i press search, it returns no result.
there are different places to apply this?
i have modified the code in ProductSerivce.cs as following:

if (!string.IsNullOrEmpty(keywords))
            {
                var langs = await _languageService.GetAllLanguagesAsync(showHidden: true);

                IQueryable<int> ExclusiveKeyWordSearch(string keywords)
                {
                    var products = _productRepository.Table;
                    var searchstrings = keywords.Split(null).Select(x => x.ToLower()).ToArray();

                    foreach (string q in searchstrings)
                    {
                        products = products.Where(p => p.Name.ToLower().Contains(q));
                    }

                    return products.Select(p => p.Id);
                }

                //Set a flag which will to points need to search in localized properties. If showHidden doesn't set to true should be at least two published languages.
                var searchLocalizedValue = languageId > 0 && langs.Count >= 2 && (showHidden || langs.Count(l => l.Published) >= 2);

                IQueryable<int> productsByKeywords;

                productsByKeywords =
                        from p in _productRepository.Table
                        where p.Name.Contains(keywords) ||
                            (searchDescriptions &&
                                (p.ShortDescription.Contains(keywords) || p.FullDescription.Contains(keywords))) ||
                            (searchManufacturerPartNumber && p.ManufacturerPartNumber == keywords) ||
                            (searchSku && p.Sku == keywords)
                        select p.Id;

                productsByKeywords = productsByKeywords.Union(ExclusiveKeyWordSearch(keywords));


thx for your help
6 months ago
any idea?
i cant get out of it
6 months ago
noffy wrote:
any idea?
i cant get out of it

i just checked with nopCommerce 4.50. everything works fine as expected.


i think any 3rd party plugin has modified your service while searching. can you give a try with default project?
6 months ago
im using 4.4.40, it may be different or it doesn't metter?