Hi I'm trying to make a movie app where I'm trying to make a search functionality work. However I'm running into a problem trying to figure out a way to make the search case insensitive as well as ignore the punctuations. I believe another post showed how to get the case insensitive to work by using regular expression
query.whereMatches("name", "("+searchData+")", "i");
However is there something I can do to ignore the punctuations?
For example in the database I have "Mission: Impossible". If a user searches for "Mission impossible" it still won't be able to find it.
A good way to search on an attribute slightly transformed is to do the transformation upon save, then use the simpler (faster) match on query against the transformed attribute. For this question, the transformation is to a case-insensitive, punctuation-free version of an attribute.
Parse.Cloud.beforeSave("MyClass", function(request, response) {
var name = request.object.get("name");
var searchName = name.replace(/['";:,.\/?\\-]/g, '').toLowerCase();
request.object.set("searchName", searchName);
response.success();
});
Now, a case-insensitive, punctuation-free search can be done with maximum simplicity and speed (since it's indexed) on the "searchName" attribute.
Related
I am trying to build a hashtag system which is similar to Twitter hashtags for an app. However, I cannot figure out how to spell such tags, when grouping different spellings together.
As an example, when you use #abc on Twitter there might be different spellings like #abc, #Abc, #aBC, etc.
When a hastag is trending it is displayed with a certain spelling in the trending list, eg. #abC and groups all different versions.
How should I determine the "correct" spelling?
I just built a hashtag system for my application and I'm not completely finished with it but my method was to get any posts that had a string of #*. Then parse that out with
GetHashes(t: string){
var hashed = t.match(/#\w+/g);
if(hashed != null){
hashed.forEach(element => {
var unhashed = element.slice(0,0) + element.slice(1,element.length);
this.hashTags.push(unhashed);
});
}else{
}
}
Then once I have all the hashes, I simply do a replace to translate everything into lowercase. That is what I send to the database. I'm using Firebase so I'm denormalizing my data and duplicating it a ton so I store the entire content of the post under the tag in the database. This might seem like a lot of data storage waste but storage is cheap. Then I don't have to implement a search system like "ElasticSearch" or "Algolia" which is expensive. (I still need to for full text search but not for hashes saving me a lot of cash).
Then when I want to return all #* I simply find that reference in the Firebase Database and viola!
What I can't figure out is how to make my hashtags links that call a function dynamically. I've been using innerHtml but that makes everything a string.
Hope this helps a bit.
Dealing with some legacy code we came across a rather annoying situation. We are looping through a query with the <cfoutput query="x"> tag. That query has a column named 'url'. Within that loop we need to check if a key exists within the url scope. Since CF puts a priority on what's in the query over general page scopes I can't use a structKeyExists(url,"key") since as far as CF is concerned at this point, url is a string with the value from the current row of the query.
How can I break out of the query scope and inspect what's in my url?
As a temporary we are using isDefined("url.key"), but I would still like to know if there is a way to break out of the query scope.
Also can't really change the column, or even the column name in the query without a few hours of work tracking down an changing all references to it, so we're going to avoid that if at all possible.
EDIT:
There seems to be some confusion as to how this code is set up, and why the simple solutions don't apply. It would be hard for me to give a thorough example but I will try to clarify the situation.
There are many pages that would count as 'pageA' for the following example. Enough that changing how things work would require a change in scope and investment in time that's just not going to happen in the time allotted.
PageA runs a query with one of the columns being named url, then starts an output loop via cfoutput, inside that loop PageB is included. One PageA may have different variables in the URL scope than another PageA, actually they are the same, but may be named differently(varID=x in one case vid=x in another). Inside of PageB I need to use the value from that url scope, so I want to run through the different possible names (if key 'varID' exists in url, use it, otherwise use 'vid').
This is why I want to "punch through" the query scope to get the url structure, and not the url column from the query. Any other method seems to require modifying the many PageAs.
So the question is not how to solve this problem specifically, as there are many ways to do it, I would just really like to avoid them as they all add a lot of time in implementation and testing. The question remains, is there a way to access the url scope as a variable if url exists as a query column and you are in the query scope.
I thought it might work to create a function that returned the url scope, but upon testing it, even with a local-scoped query (which prevents the function using the query itself) the use of url inside the function is still corrupted:
<cffunction name="getUrlScope"><cfreturn Url /></cffunction>
...
<cfoutput query="x">
<cfif StructKeyExists( getUrlScope() , 'key' )>
<!--- still fails :( --->
There is however an undocumented (meaning unsupported and liable to change) option. If you dump getPageContext() you will see a bunch of functions that do interesting things, including dealing with scopes.
You can use getPageContext().SymTab_findBuiltinScope('URL') to get at the URL scope.
You can also use getPageContext().getCfScopes() to get an array of scopes. I'm not sure if the order is guaranteed fixed but it seems to be [cgi,?,url,form,cookie,?] checking on both CF10 and cflive (CF9), so possibly is.
(In CF8 there was the method getBuiltinScopes, which returned a struct instead of an array - this no longer appears to exist, reinforcing the whole unsupported and changeable nature of these methods.)
On Railo those don't work, but there is getPageContext.UrlScope() and similarly-named functions for the other scopes.
One solution would be to assign the url struct to a new variable outside of the cfoutput tag and then reference that variable instead of url. Example:
<cfset urlScope = url>
<cfoutput query="x">
<cfset keyExists = structKeyExists(urlScope, "key")>
</cfoutput>
My solution for this is always to alias the url column in the query as int
SELECT URL as qURL FROM myTable ...
IF you don't have access to the query (it's a stored precedure or used elswhere etc) you can always use query of a query to reselect it with your alias.
I don't care for the idea of creating a separate reference to URL outside the output - but that would also work. I just want to KNOW what is user input (i.e. comes from the URL or FORM) and what is generated internally (i.e. comes from a query).
Couldn't you move structKeyExists(url,"key") outside of the cfoutput block, and store that into a variable? Or do a structAppend to copy the url struct into another struct named something else?
Another approach is to replace your cfoutput block with a cfloop block.
<cfloop from="1' to = "#YourQuery.recordcount#" index = "idx">
<cfif StructKeyExits(url,"key")>
<cfoutput>
#url.key# is not the same as #YourQuery.url[idx]#
which can also be referenced like this #YourQuery["url"][idx]
etc
I'm currently creating a search function in lua which basically just goes through a list of items and processes the items that match the input string in a specific way.
I use string.find(sourceString, inputString) to identify the items.
The function is called whenever a user types something into a text field so if he tries to enter a pattern it happens that when using sets or captures the function is called when the search string just contains a [ or a ( without the closing equivalent which of cause throws an error.
The best way to go around this problem I think is to validate the input as beeing a valid pattern, but I've got no idea how to do this. Lua itself doesn't seem to contain a method for this and I am a bit confused of how to check it in a more or less performant way myself. Thanks for your help and ideas in advance :)
You should wrap the call to string.find with pcall to capture the error.
local status, result = pcall(string.find, sourceString, inputString)
if not status then
-- bad pattern logic, error message is in result
else
-- good pattern logic, result contains the start index
end
See this for pattern escape function (taken from somewhere in Lua Users wiki, I think). You may convert it to the validation function if you need.
What's the best way to implement an interface that looks like this in rails?
Currently I'm using Searchlogic, and it's a tad painful. Problems include:
Making sure certain operations remain orthogonal -- for example, if you select "Short Posts" and then search, your search results should be restricted to short posts.
Making sure the correct link gets the "selected" class. Right now the links are <a>'s, so maintaining this state client-side is tricky. I'm hacking it by having the AJAX response to, say, sorting return a new sort links section with the correct link "selected". Using radio buttons instead of <a> tags would make it easier to maintain state client-side -- maybe I should do that?
I recently solved a similar problem using named_scopes and some ruby metaprogramming that I rolled up into a plugin called find_by_filter.
find_by_filter accepts a hash of scope
names and values, and chains them into
parametised scope calls. If the model has a named_scope that matches the provided name, this is called.If no named_scope is found, an anonymous scope is created.
I've seen some websites highlight the search engine keywords you used, to reach the page. (such as the keywords you typed in the Google search listing)
How does it know what keywords you typed in the search engine? Does it examine the referrer HTTP header or something? Any available scripts that can do this? It might be server-side or JavaScript, I'm not sure.
This can be done either server-side or client-side. The search keywords are determined by looking at the HTTP Referer (sic) header. In JavaScript you can look at document.referrer.
Once you have the referrer, you check to see if it's a search engine results page you know about, and then parse out the search terms.
For example, Google's search results have URLs that look like this:
http://www.google.com/search?hl=en&q=programming+questions
The q query parameter is the search query, so you'd want to pull that out and un-URL-escape it, resulting in:
programming questions
Then you can search for the terms on your page and highlight them as necessary. If you're doing this server side-you'd modify the HTML before sending it to the client. If you're doing it client-side you'd manipulate the DOM.
There are existing libraries that can do this for you, like this one.
Realizing this is probably too late to make any difference...
Please, I beg you -- find out how to accomplish this and then never do it. As a web user, I find it intensely annoying (and distracting) when I come across a site that does this automatically. Most of the time it just ends up highlighting every other word on the page. If I need assistance finding a certain word within a page, my browser has a much more appropriate "find" function built right in, which I can use or not use at will, rather than having to reload the whole page to get it to go away when I don't want it (which is the vast majority of the time).
Basically, you...
Examine document.referrer.
Have a list of domains to GET param that contains the search terms.
var searchEnginesToGetParam = {
'google.com' : 'q',
'bing.com' : 'q'
}
Extract the appropriate GET param, and decodeURIComponent() it.
Parse the text nodes where you want to highlight the terms (see Replacing text with JavaScript).
You're done!