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 Offline
    T Offline
    tonyonlinux
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • 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