Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. LINQ
  4. Trying to do a keyword search but not sure how to use the contains method [modified]

Trying to do a keyword search but not sure how to use the contains method [modified]

Scheduled Pinned Locked Moved LINQ
tutorialdatabasequestion
14 Posts 2 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T tonyonlinux

    I have a field in my database for tags the user can enter like "soda coke drinker or drinker soda coke ....." I understand I can find with contains

    var results = from o in Database.Readall()
    where o.tags.Contains(userTags)
    select new .......

    Lets say I have in my database Customers a field called tags. Inside there it has coke drinker. then another field has coffee drinker A user comes along and wishes to find that record all drinkers i know i could do a customers.tags.contains(tags) and if they entered say drinker it would find both the coke drinker and the coffee drinker but what if they entered drinker coke or drinker coffee it would not find either one. because it would be looking for %drinker coke% or %drinker coffee% which doesn't exist in that order. How can you make it where it doesn't matter what order the words are in but actually checks to see if ANY of the words exist in that field ? an example would be great thanks

    modified on Friday, February 26, 2010 8:40 AM

    D Offline
    D Offline
    Dan Mos
    wrote on last edited by
    #2

    the .Contains() method is used to find items that Contain the specified "item". I would go for: 1) Predicate/Func or 2) A method like:

    public bool MyContains(string tags, string user){
    string[]separateWords = user.Split(" ");//just an example
    foreach(var str in separateWords){
    if(tags.Contains(str)){return true;}
    }
    return false;
    }

    If 2) change your where clause to something like this:

    where MyContains(o.tags, usewrTags)

    T 1 Reply Last reply
    0
    • D Dan Mos

      the .Contains() method is used to find items that Contain the specified "item". I would go for: 1) Predicate/Func or 2) A method like:

      public bool MyContains(string tags, string user){
      string[]separateWords = user.Split(" ");//just an example
      foreach(var str in separateWords){
      if(tags.Contains(str)){return true;}
      }
      return false;
      }

      If 2) change your where clause to something like this:

      where MyContains(o.tags, usewrTags)

      T Offline
      T Offline
      tonyonlinux
      wrote on last edited by
      #3

      Thanks. I used method two and it works perfectly. I have one more question to ask. how would I I make it search where it contains both words? I see here it does a foreach on the split string and sees if it is inside the o.whatever and it works like it should if i enter say coke it finds everything that has coke in it. but if i specifically wanted the to display items containing where both the words exist in any sequence how would that be done ? Like if i have tags pizza coke drinker and another tag eggs coke and i enter in the search coke drinker. with the method you showed it would pull up both records. but i only want the one where BOTH words match? I'm sorry for all the questions this is really new to me. Thanks for your help.

      D 1 Reply Last reply
      0
      • T tonyonlinux

        Thanks. I used method two and it works perfectly. I have one more question to ask. how would I I make it search where it contains both words? I see here it does a foreach on the split string and sees if it is inside the o.whatever and it works like it should if i enter say coke it finds everything that has coke in it. but if i specifically wanted the to display items containing where both the words exist in any sequence how would that be done ? Like if i have tags pizza coke drinker and another tag eggs coke and i enter in the search coke drinker. with the method you showed it would pull up both records. but i only want the one where BOTH words match? I'm sorry for all the questions this is really new to me. Thanks for your help.

        D Offline
        D Offline
        Dan Mos
        wrote on last edited by
        #4

        that's simple inverse the logic meaning

        foreach(vat srt in words){
        if (!tags.Contains(str)) {return false};
        }
        return true;//if it gets to this point means that it did not find a single word that is not
        //contained in the tags so all of them were found

        T 1 Reply Last reply
        0
        • D Dan Mos

          that's simple inverse the logic meaning

          foreach(vat srt in words){
          if (!tags.Contains(str)) {return false};
          }
          return true;//if it gets to this point means that it did not find a single word that is not
          //contained in the tags so all of them were found

          T Offline
          T Offline
          tonyonlinux
          wrote on last edited by
          #5

          well duh :( I feel really dumb on that one cause like you say that was simple. Thanks again for your help I really appreciate it.

          D 1 Reply Last reply
          0
          • T tonyonlinux

            well duh :( I feel really dumb on that one cause like you say that was simple. Thanks again for your help I really appreciate it.

            D Offline
            D Offline
            Dan Mos
            wrote on last edited by
            #6

            no problem. And DONT feel dumb. I almost screw up my career some time ago because I felt dumb and did not have the patiance to read tones of documentation. But I didn't. Because other help me(not in here CP but you got the ideea) ;)

            T 2 Replies Last reply
            0
            • D Dan Mos

              no problem. And DONT feel dumb. I almost screw up my career some time ago because I felt dumb and did not have the patiance to read tones of documentation. But I didn't. Because other help me(not in here CP but you got the ideea) ;)

              T Offline
              T Offline
              tonyonlinux
              wrote on last edited by
              #7

              Thanks, I will take your advice. I read a lot but sometimes the examples are poor or simply wrong. Also, i have a hard time comprehending things (always have just a part of my life). Anyway, thanks for your kind words.

              1 Reply Last reply
              0
              • D Dan Mos

                no problem. And DONT feel dumb. I almost screw up my career some time ago because I felt dumb and did not have the patiance to read tones of documentation. But I didn't. Because other help me(not in here CP but you got the ideea) ;)

                T Offline
                T Offline
                tonyonlinux
                wrote on last edited by
                #8

                Hey I know we have talked on this before. Still have an issue with it a little bit. What is happening is if i type in say lifeskills i will get a result for that. and also the match all works where if i typed in lifeskills christmas. That works perfectly the problem is it checks for the "whole word". Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ? here is what i have so far thanks for your previous help by the way...

                    public static IEnumerableGetbyKeywordLookup(string keywords)
                    {
                       
                           var results = from o in BookProxy.Readall()
                          //var results = from o in BookProxy.ReadallbyTags(keywords)
                                      where MyContains(o.TagName,keywords.Trim())
                                      
                                      select new GridProxy
                                      {
                                          Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                          AuthorID = o.AuthorID,
                                          AuthorFirst = o.AuthorFirstname,
                                          AuthorSurname = o.AuthorSurname,
                                          TagID = o.TagID,
                                          BookID = o.bookID,
                                          ISBN = o.ISBN,
                                          BookNumber = o.RefNumber,
                                          BookTitle = o.Title,
                                          Count = BookNumberProxy.getall().Count(c => c.BOOK\_ID == o.bookID)
                                      };
                           printerlist = results.ToList();
                        var distinct = results.GroupBy(o => o.ISBN).Select(o => o.FirstOrDefault());
                        return distinct.ToList();
                    }
                
                    public static IEnumerable GetbyKeywordLookupAll(string keywords)
                    {
                        
                        var results = from o in BookProxy.Readall()
                                      where MyContainsAll(o.TagName, keywords.Trim())
                
                                      select new GridProxy
                                      {
                                          Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                          AuthorID = o.AuthorID,
                                          AuthorFirst = o.AuthorFirstname,
                                          AuthorSurname = o.AuthorSurname,
                                          TagID = o.TagID,
                                          BookID = o.bookID,
                                          ISBN = o.ISBN,
                
                D 1 Reply Last reply
                0
                • T tonyonlinux

                  Hey I know we have talked on this before. Still have an issue with it a little bit. What is happening is if i type in say lifeskills i will get a result for that. and also the match all works where if i typed in lifeskills christmas. That works perfectly the problem is it checks for the "whole word". Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ? here is what i have so far thanks for your previous help by the way...

                      public static IEnumerableGetbyKeywordLookup(string keywords)
                      {
                         
                             var results = from o in BookProxy.Readall()
                            //var results = from o in BookProxy.ReadallbyTags(keywords)
                                        where MyContains(o.TagName,keywords.Trim())
                                        
                                        select new GridProxy
                                        {
                                            Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                            AuthorID = o.AuthorID,
                                            AuthorFirst = o.AuthorFirstname,
                                            AuthorSurname = o.AuthorSurname,
                                            TagID = o.TagID,
                                            BookID = o.bookID,
                                            ISBN = o.ISBN,
                                            BookNumber = o.RefNumber,
                                            BookTitle = o.Title,
                                            Count = BookNumberProxy.getall().Count(c => c.BOOK\_ID == o.bookID)
                                        };
                             printerlist = results.ToList();
                          var distinct = results.GroupBy(o => o.ISBN).Select(o => o.FirstOrDefault());
                          return distinct.ToList();
                      }
                  
                      public static IEnumerable GetbyKeywordLookupAll(string keywords)
                      {
                          
                          var results = from o in BookProxy.Readall()
                                        where MyContainsAll(o.TagName, keywords.Trim())
                  
                                        select new GridProxy
                                        {
                                            Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                            AuthorID = o.AuthorID,
                                            AuthorFirst = o.AuthorFirstname,
                                            AuthorSurname = o.AuthorSurname,
                                            TagID = o.TagID,
                                            BookID = o.bookID,
                                            ISBN = o.ISBN,
                  
                  D Offline
                  D Offline
                  Dan Mos
                  wrote on last edited by
                  #9

                  Hy,

                  tonyonlinux wrote:

                  Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ?

                  Your methods are [Edit] NOT [/Edit] OK. [Edit] Don't split the tag(s) If you use List.Contains(item) it will call the Equals Method of the underling type in this case string. Ex:

                  "Apples Oranges".Contains("Apple")=>true
                  "Apples Oranges".Contains("Orange")=>true

                  But myList.Add("Apples");
                  myList.Add("Oranges");

                  and then call myList.Contains("Apple") =>false

                  [/Edit] Anyway: Suppose we have a tag of "My lions are eating lots of food". And user input "lion lot"; Well this code will find both of them and as a bonus return the hole word from tag => eg lions for lion and lots for lot.

                  string tag = "My lions are eating lots of food";
                  string user = "lion lot";

                  List<String> matches = new List<string>();

                  string[] words = user.Split(' ');
                  foreach (var item in words)
                  {
                  if (tag.Contains(item))//it finds 'lion' in 'lions' and 'lot' in 'lots'
                  {
                  matches.Add(GetFullItem(tag, item));//returns the full word from the tags
                  //eg lions for lion...
                  }
                  }

                  //and here's a GetFullItem
                  private string GetFullItem(string tag, string item)
                  {
                  //get start of the word (the location/index)
                  int idxStrat = tag.IndexOf(item);
                  //get the First Index of space after the start location for the current word
                  //=>the idxEnd
                  int idxEnd = tag.IndexOf(" ", idxStrat);
                  //now get the length
                  int length = idxEnd-idxStrat;
                  //finally return the hole string( eg lions instead of lion and lots instead of lot
                  return tag.Substring(idxStart,length);
                  }

                  modified on Sunday, March 7, 2010 10:36 AM

                  T 1 Reply Last reply
                  0
                  • D Dan Mos

                    Hy,

                    tonyonlinux wrote:

                    Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ?

                    Your methods are [Edit] NOT [/Edit] OK. [Edit] Don't split the tag(s) If you use List.Contains(item) it will call the Equals Method of the underling type in this case string. Ex:

                    "Apples Oranges".Contains("Apple")=>true
                    "Apples Oranges".Contains("Orange")=>true

                    But myList.Add("Apples");
                    myList.Add("Oranges");

                    and then call myList.Contains("Apple") =>false

                    [/Edit] Anyway: Suppose we have a tag of "My lions are eating lots of food". And user input "lion lot"; Well this code will find both of them and as a bonus return the hole word from tag => eg lions for lion and lots for lot.

                    string tag = "My lions are eating lots of food";
                    string user = "lion lot";

                    List<String> matches = new List<string>();

                    string[] words = user.Split(' ');
                    foreach (var item in words)
                    {
                    if (tag.Contains(item))//it finds 'lion' in 'lions' and 'lot' in 'lots'
                    {
                    matches.Add(GetFullItem(tag, item));//returns the full word from the tags
                    //eg lions for lion...
                    }
                    }

                    //and here's a GetFullItem
                    private string GetFullItem(string tag, string item)
                    {
                    //get start of the word (the location/index)
                    int idxStrat = tag.IndexOf(item);
                    //get the First Index of space after the start location for the current word
                    //=>the idxEnd
                    int idxEnd = tag.IndexOf(" ", idxStrat);
                    //now get the length
                    int length = idxEnd-idxStrat;
                    //finally return the hole string( eg lions instead of lion and lots instead of lot
                    return tag.Substring(idxStart,length);
                    }

                    modified on Sunday, March 7, 2010 10:36 AM

                    T Offline
                    T Offline
                    tonyonlinux
                    wrote on last edited by
                    #10

                    so your are saying do this ?

                    private static bool MyContains(string tags, string user)
                    {

                            List seperatewords = new List(user.Split(' ').ToList());
                            List seperateTags = new List(tags.Split(' ').ToList());
                            //new
                            List matches = new List();
                            foreach (var str in seperatewords)
                            {
                                string stringvalue = str.ToString();
                                //new 
                                if (tags.Contains(str))
                                {
                                    matches.Add(GetfullText(tags, str));
                                    
                                }
                    
                                //end new
                                //original  if (seperateTags.Contains(str, StringComparer.CurrentCultureIgnoreCase)) { return true; }
                                if (tags.Contains(matches.ToString(), StringComparer.CurrentCultureIgnoreCase)) { return true; }
                            }
                            return false;
                        }
                    
                        private static string GetfullText(string tags, string str)
                        {
                            //get start of the word (the location/index)
                            int idxStrat = tags.IndexOf(str);
                            //get the First Index of space after the start location for the current word
                            //=>the idxEnd
                            int idxEnd = tags.IndexOf(" ", idxStrat);
                            //now get the length
                            int length = idxEnd - idxStrat;
                            //finally return the hole string( eg lions instead of lion and lots instead of lot
                            return tags.ToString().Substring(idxStrat, length); ;
                        }
                    

                    :( i'm confused still sorry

                    D 1 Reply Last reply
                    0
                    • T tonyonlinux

                      so your are saying do this ?

                      private static bool MyContains(string tags, string user)
                      {

                              List seperatewords = new List(user.Split(' ').ToList());
                              List seperateTags = new List(tags.Split(' ').ToList());
                              //new
                              List matches = new List();
                              foreach (var str in seperatewords)
                              {
                                  string stringvalue = str.ToString();
                                  //new 
                                  if (tags.Contains(str))
                                  {
                                      matches.Add(GetfullText(tags, str));
                                      
                                  }
                      
                                  //end new
                                  //original  if (seperateTags.Contains(str, StringComparer.CurrentCultureIgnoreCase)) { return true; }
                                  if (tags.Contains(matches.ToString(), StringComparer.CurrentCultureIgnoreCase)) { return true; }
                              }
                              return false;
                          }
                      
                          private static string GetfullText(string tags, string str)
                          {
                              //get start of the word (the location/index)
                              int idxStrat = tags.IndexOf(str);
                              //get the First Index of space after the start location for the current word
                              //=>the idxEnd
                              int idxEnd = tags.IndexOf(" ", idxStrat);
                              //now get the length
                              int length = idxEnd - idxStrat;
                              //finally return the hole string( eg lions instead of lion and lots instead of lot
                              return tags.ToString().Substring(idxStrat, length); ;
                          }
                      

                      :( i'm confused still sorry

                      D Offline
                      D Offline
                      Dan Mos
                      wrote on last edited by
                      #11

                      No I, saying to do this:

                      private static bool MyContains(string tags, string user)
                      {
                      List seperatewords = new List(user.Split(' ').ToList());
                      //List seperateTags = new List(tags.Split(' ').ToList());//get rid of this
                      foreach (var str in seperatewords)
                      {
                      string stringvalue = str.ToString();
                      if (tags.Contains(str))
                      {
                      //matches.Add(...) this is optional just an example but you don't really need it
                      return true;
                      }
                      }
                      return false;

                      T 2 Replies Last reply
                      0
                      • D Dan Mos

                        No I, saying to do this:

                        private static bool MyContains(string tags, string user)
                        {
                        List seperatewords = new List(user.Split(' ').ToList());
                        //List seperateTags = new List(tags.Split(' ').ToList());//get rid of this
                        foreach (var str in seperatewords)
                        {
                        string stringvalue = str.ToString();
                        if (tags.Contains(str))
                        {
                        //matches.Add(...) this is optional just an example but you don't really need it
                        return true;
                        }
                        }
                        return false;

                        T Offline
                        T Offline
                        tonyonlinux
                        wrote on last edited by
                        #12

                        thanks for your help but it is still not working. I tried what you posted above. but i get no results what so ever now. I think it has something to do with not having the stringcomparer.cultureignorecase in there. I tried to put it back in there but it doesn't like the fact that tags is not that of a list :(

                        D 1 Reply Last reply
                        0
                        • D Dan Mos

                          No I, saying to do this:

                          private static bool MyContains(string tags, string user)
                          {
                          List seperatewords = new List(user.Split(' ').ToList());
                          //List seperateTags = new List(tags.Split(' ').ToList());//get rid of this
                          foreach (var str in seperatewords)
                          {
                          string stringvalue = str.ToString();
                          if (tags.Contains(str))
                          {
                          //matches.Add(...) this is optional just an example but you don't really need it
                          return true;
                          }
                          }
                          return false;

                          T Offline
                          T Offline
                          tonyonlinux
                          wrote on last edited by
                          #13

                          nevermind i think i got it it looks like i did anyway when i ran some test. I simply took and did the following on the if statement.

                          if (tags.toUpper().Contains(str.ToUpper))
                          {
                          return true;
                          }

                          thanks again

                          1 Reply Last reply
                          0
                          • T tonyonlinux

                            thanks for your help but it is still not working. I tried what you posted above. but i get no results what so ever now. I think it has something to do with not having the stringcomparer.cultureignorecase in there. I tried to put it back in there but it doesn't like the fact that tags is not that of a list :(

                            D Offline
                            D Offline
                            Dan Mos
                            wrote on last edited by
                            #14

                            OK. Maybe I understood you wrong. Here's what I think you need to acomplish => correct me if I'm wrong. So, you need to get like all the data about books based on the book keywords/tags and the keywords introduced by user. If that's what you need then this is a working solution: (feel free to create a new windows app, add 2 buttons and paste the code to check):

                            /// <summary>
                            /// check if contains any keywords
                            /// </summary>
                            /// <param name="sender"></param>
                            /// <param name="e"></param>
                            private void btnContainsAny_Click(object sender, EventArgs e)
                            {
                            string tags = "science fiction futurist 1024 cores 25 GHz";
                            string user = "fiction core";
                            if (MyContainsAny(tags, user))
                            {
                            string message =
                            String.Format("At least one keyword form \"{0}\" was found in \r\n" +
                            "\"{1}\"", user, tags);
                            MessageBox.Show(message);
                            }
                            }

                                /// <summary>
                                /// check if contains all keywords
                                /// </summary>
                                /// <param name="sender"></param>
                                /// <param name="e"></param>
                                private void btnContainsAll\_Click(object sender, EventArgs e)
                                {
                                    string tags = "science fiction futurist 1024 cores 25 GHz";
                                    string user = "fiction core";
                                    if (MyContainsAll(tags, user))
                                    {
                                        string message =
                                            String.Format("All the keywords form \\"{0}\\" were found in \\r\\n" +
                                            "\\"{1}\\"", user, tags);
                                        MessageBox.Show(message);//as you can see it finds core in cores
                                    }
                                }        
                            
                            
                                /// <summary>
                                /// used to see if the tag contains ANY of the keywords introduced by user
                                /// </summary>
                                /// <param name="tag"></param>
                                /// <param name="userData"></param>
                                /// <returns></returns>
                                private bool MyContainsAny(string tag, string userData)
                                {
                                    string\[\] words = userData.Trim().Split(" ");
                                    foreach (var item in words)
                                    {
                                        if (tag.Contains(item)) { return true; }
                                    }
                                    return false;
                                }
                            
                                /// <summary>
                                /// used to see if the tag contains ALL of the keywords introduced by user
                                /// </
                            
                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups