Search matching only ends of strings

Home Forums Product Support Forums Ajax Search Pro for WordPress Support Search matching only ends of strings

This topic contains 6 replies, has 2 voices, and was last updated by

 
Keymaster
6 years, 1 month ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #6654

    Participant

    I currently have the plugin set to search a custom field for zip codes using the Regular search engine. Client wants the search to match for 3 digits, but it appears to only be matching for the ends of strings….

    Specifically if a user searches:
    – 5 digit zip code of 12345 = returns one post containing the full 12345 zip (our target post = success!)

    – 4 digits of a zip code 1234 = returns the target post with 12345, but also 12346, 12347 – 81234, 91234 … a mix of start on end of string matches; which is fine as long as the target is found.

    – 3 digits of a zip 123 = returns ONLY matches from the ends of strings like 56123, 78123, etc…. The 3 digit search fails to match the target post containing 12345

    Three digit searches also fail to pull in other results like 12367, 12378, 12389, etc… it only matches the ends of the strings.

    Could this be a formatting issue on my end? or a setting in the plugin that I am missing?
    Please let me know if we cant get this working with only 3 digit searches
    thank you very much!

    #6658

    Hi!

    I’m guessing this is stored in a custom field?

    The only possible explanation I can see in this case is that there are lots of posts ending “123” and then beginning “123”. There is no difference searching 3 or 4 digits on database level, so if it works on 4 digits, it must work on 3 as well.
    The case is probably that for example the limit is set to 10 posts. The plugin passes the query to the database and it returns the first 10 matching results with the highest relevance. If the first 10 matching contain 123 either on the beginning, the end or in the middle it’s immediately returned. In this case the relevance is the same for any case.

    I think I might have a solution though 🙂 If you are indeed using custom fields, then open up the wp-content/plugins/ajax-search-pro/includes/search/search_content.class.php file and go to line 813 and 824, the two lines should be identical, something like:

    $parts[] = "( $wpdb->postmeta.meta_key='$cfield' AND ...

    Then, add this line just below both of those two lines:

    $relevance_parts[] = "(case when ($wpdb->postmeta.meta_key='$cfield' AND " . $pre_field . $wpdb->postmeta . ".meta_value" . $suf_field . " LIKE $pre_like'" . $_like . "%'$suf_like) then 50 else 0 end)";

    This will increase the relevance in case the search string is found on the beginning of the word by 50, which ensures that those results are displayed first. I just tested this, it seems to be working as expected.

    Let me know if anything changes!

    Best,
    Ernest Marcinko

    If you like my products, don't forget to rate them on codecanyon :)


    #6864

    Participant

    Thank you so much for the code snippet! Sorry for delayed response!

    Setting the plugin to show more values did indeed show the target post so the plugin working just fine.
    However the snippet you provided doesnt appear to be working (or maybe I need it to work slightly differently***)

    For example:
    search “12345” shows one post with one make within the custom field
    search “1234” shows 3 posts and the first result contains 3 matches from within the custom field (others have fewer)
    search “123” shows 30+ posts but the first results only contain 1 match while the target post has more then 45 matches and is shown 17th in the list

    *** Is there a way to also apply weight based on the number of matches from within the field? This way a post with more matches shows up first or at least higher in the results?

    #6865

    Participant

    Also after testing some more tonight it appears that their publish date is effecting their position in the results. Our target post was older but showed up on top when I set the publish date to today. Even though we have Relevance options set and the snippet you provided it appears to be using the publish date for result ordering…

    Is there a way to set the ordering based on the number of hits a result contains?

    thank you!

    #6868

    Hi!

    “search “123” shows 30+ posts but the first results only contain 1 match while the target post has more then 45 matches and is shown 17th in the list”

    The issue with the regular engine is, that it cannot count matches. For example a result with 100 matches in the content, and another with only 1 match in the content gets the same relevance. There is no way around it. Implementing a counting mechanism is not an option, since it’s extremely performance heavy operation in this case.

    I strongly suggest to consider using the Index Table engine. It basically generates a database table with all the words in all the matching posts and fields. The great thing is however, that this solves the counting problem. Because it is a list of indexed keywords, it stores the occurences of each keyword in each field – so the calculation of the relevance is very precise.

    Another great thing is that you won’t need that custom code, as keywords extracted from content or custom fields are treated equally on the database level. In the latest version of the plugin (4.6) I’ve added a few new options to the relevance panel, where it is now possible to adjust the Index table relevance values separately. I’ve also implemented an adjustable primary and a secondary ordering, to clear the smoke around relevance-data ordering problems.

    Best,
    Ernest Marcinko

    If you like my products, don't forget to rate them on codecanyon :)


    #6875

    Participant

    Awesome!
    I was thinking of using the index table but didnt know if it would work with my custom field value because each post has a long list of comma separated strings: “12345, 12445, 12545, 12645”

    And I need to be able to match from the middle of that list and/or the beginning of a each list value
    (ex: matching “125” as part of “12545” from within the list above)

    Could you please let me know if this is possible and if so I will gladly swap over to using the index table!
    If not – would storing the values in any other way make this easier (without commas, without spaces, etc…)

    Thank you so much for your help btw = you have been most detailed in your responses!
    I know my request is rather odd and I am trying to steer my client to the most efficient and logical solution, but you know how that goes!

    #6887

    You are welcome 🙂

    Well it’s not possible with the index table in sense of the performance. There is a MySQL behavior that the index table uses to gain performance. Basically the database can create so called “indexes” that are accessible at a very low cost in a very high speed. There are limitations however to use these indexes – especially when searching. The limitation is that you can only search from the beginning of the words. (the ending is solved by storing the reverse of the string in the same table). If you however decide to look for matches within the words then the database will not use these indexed values for fast access, since the foundation of the index is that the matching has to begin with the first character.
    The reason why is it like this is roots in rather complicated math and binary trees and such.

    Basically the index table engine provides very precise matches at high speed but at the cost of not be able to search in the middle. The regular engine provides wider set of matches, but the relevance is much worse.

    I can suggest a modification to be able to look in the “middle” of the indexed values, but I strongly recommend testing it before live usage. I have never tried that, and it might cause large performance peaks in the mysql process on your server.

    Open up the wp-content/plugins/ajax-search-pro/includes/search/search_indextable.class.php file and scroll to line 564, which should be this:

    $like_query = "asp_index.term LIKE '".$word."%'";

    change that line to:

    $like_query = "asp_index.term LIKE '%".$word."%'";

    and that’s it. The index table engine now should be returning results even if it matches words in the middle.

    Best,
    Ernest Marcinko

    If you like my products, don't forget to rate them on codecanyon :)


Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.