Google Local Search and Markers - google-local-search

I'm following the code located at this page:
http://code.google.com/apis/ajax/playground/#localsearch_with_markers
the search the demo shows is:
// Execute an initial search
searchControl.execute('pizza');
How can I get it to search more than one term? For example something equivalent to:
// Execute an initial search
searchControl.execute('pizza');
searchControl.execute('coffee');
This method will only return the 'coffee' results. It completely ignores 'pizza'.
From reviewing this demo it appears to be possible...
http://code.google.com/apis/ajax/playground/#the_hello_world_of_local_search
if you look at the following code:
// Specify search quer(ies)
localSearch.execute('coffee New York NY');
and change it to:
// Specify search quer(ies)
localSearch.execute('pizza');
localSearch.execute('coffee');
It will return both pizza and coffe results. Any ideas to get this to show up on the map though?

Related

AEM Query builder exclude a folder in search

I need to create a query where the params are like:
queryParams.put("path", "/content/myFolder");
queryParams.put("1_property", "myProperty");
queryParams.put("1_property.operation", "exists");
queryParams.put("p.limit", "-1");
But, I need to exclude a certain path inside this blanket folder , say: "/content/myFolder/wrongFolder" and search in all other folders (whose number keeps on varying)
Is there a way to do so ? I didn't find it exactly online.
I also tried the unequals operation as the parent path is being saved in a JCR property, but still no luck. I actually need unlike to avoid all occurrences of the path. But there is no such thing:
path=/main/path/to/search/in
group.1_property=cq:parentPath
group.1_property.operation=unequals
group.1_property.value=/path/to/be/avoided
group.2_property=myProperty
group.2_property.operation=exists
group.p.or=true
p.limit=-1
This is an old question but the reason you got more results later lies in the way in which you have constructed your query. The correct way to write a query like this would be something like:
path=/main/path/where
property=myProperty
property.operation=exists
property.value=true
group.p.or=true
group.p.not=true
group.1_path=/main/path/where/first/you/donot/want/to/search
group.2_path=/main/path/where/second/you/donot/want/to/search
p.limit=-1
A couple of notes: your group.p.or in your last comment would have applied to all of your groups because they weren't delineated by a group number. If you want an OR to be applied to a specific group (but not all groups), you would use:
path=/main/path/where
group.1_property=myProperty
group.1_property.operation=exists
group.1_property.value=true
2_group.p.or=true
2_group.p.not=true
2_group.3_path=/main/path/where/first/you/donot/want/to/search
2_group.4_path=/main/path/where/second/you/donot/want/to/search
Also, the numbers themselves don't matter - they don't have to be sequential, as long as property predicate numbers aren't reused, which will cause an exception to be thrown when the QB tries to parse it. But for readability and general convention, they're usually presented that way.
I presume that your example was just thrown together for this question, but obviously your "do not search" paths would have to be children of the main path you want to search or including them in the query would be superfluous, the query would not be searching them anyway otherwise.
AEM Query Builder Documentation for 6.3
Hope this helps someone in the future.
Using QueryBuilder you can execute:
map.put("group.p.not",true)
map.put("group.1_path","/first/path/where/you/donot/want/to/search")
map.put("group.2_path","/second/path/where/you/donot/want/to/search")
Also I've checked PredicateGroup's class API and they provide a setNegated method. I've never used it myself, but I think you can negate a group and combine it into a common predicate with the path you are searching on like:
final PredicateGroup doNotSearchGroup = new PredicateGroup();
doNotSearchGroup.setNegated(true);
doNotSearchGroup.add(new Predicate("path").set("path", "/path/where/you/donot/want/to/search"));
final PredicateGroup combinedPredicate = new PredicateGroup();
combinedPredicate.add(new Predicate("path").set("path", "/path/where/you/want/to/search"));
combinedPredicate.add(doNotSearchGroup);
final Query query = queryBuilder.createQuery(combinedPredicate);
Here is the query to specify operator on given specific group id.
path=/content/course/
type=cq:Page
p.limit=-1
1_property=jcr:content/event
group.1_group.1_group.daterange.lowerBound=2019-12-26T13:39:19.358Z
group.1_group.1_group.daterange.property=jcr:content/xyz
group.1_group.2_group.daterange.upperBound=2019-12-26T13:39:19.358Z
group.1_group.2_group.daterange.property=jcr:content/abc
group.1_group.3_group.relativedaterange.property=jcr:content/courseStartDate
group.1_group.3_group.relativedaterange.lowerBound=0
group.1_group.2_group.p.not=true
group.1_group.1_group.p.not=true

How to use MarkLogic search options by name

I'm using the ML9 Java API to upload a search options file to the DB with a name that I can use later in my search call. I would now like to write an xquery transform to highlight the query-matches in a set of elements in the response. Standard snippets won't work for me since they only bring back the fields in which there are matches and because they may not bring back the complete field value, but only the immediate context of the match.
So I want to use the cts:highlight function in a custom transform and want to pass to it the name of the options that I have uploaded into the DB. My question is how I can best get the options element from the DB using the name passed in to the transform method. I want to use this to construct the cts:query that I can pass in to the cts:highlight call as in:
let $query := cts:query(search:parse($query-string, $options))
let $result := cts:highlight($doc, $query, <markup>{$cts:text}
</markup>)
I was thinking I could pass in the query-string and the name of the pre-loaded options and use these to construct the cts:query, but don't know how to get the options from the name.
I found a way to avoid having to read the options. Setting the option 'return-query' to true adds a search:query node to the search:response which is passed to the transform method as the document-node. I'm then able to get this directly in the transform method to use in cts:highlight as:
let $query := cts:query($response/search:response/search:query/*[1])
The options are stored in the modules database associated with your REST instance. You could theoretically dig them out, though that would be relying on an implementation detail (the URI).
You might look into a combination of extract-document-data, as Sam mentioned, plus a search result transform, rather than the heavier approach of doing your own search through what I'd guess is a read transform.
Another alternative might be a custom snippeter that you pull into your options via transform-results. See http://docs.marklogic.com/guide/search-dev/query-options#id_58295.

Can I restrict Easy Search to only return published data?

I'm using matteodem's Easy Search package and have just discovered that instead of returning only published documents, the searches have access to the entire collection.
I've tested this by setting my publish function to return an empty array, and then checking that MyCollection.find().fetch() in the console correctly returns []. But searching MyCollection with Easy Search still returns all matching documents in the collection.
Is there any way to ensure that Easy Search only passes permitted data up to the client? I can't find anything in the documentation.
Easy Search is running the search on the server where it has universal access. According to the docs you can setup a default selector to filter the search by some criteria. In your case you can just copy the selector from your normal publication (the first parameter in your publication's find()) and set that as the default selector for Easy Search.
let index = new EasySearch.Index({
collection: someCollection,
fields: ['name'],
engine: new EasySearch.Minimongo({
sort: () => ['score'], // sort by score
selector: function (searchObject, options, aggregation) {
// selector contains the default mongo selector that Easy Search would use
let selector = this.defaultConfiguration().selector(searchObject, options, aggregation);
// modify the selector to only match documents created by the current user
selector.createdBy = this.userId || options.search.userId; // to run on both client and server
return selector;
}
})
});
From matteodem, the developer of Easy Search, I have a simple answer to my original question of how to ensure that only published data are returned by a search.
The easiest way is to use a client-side search engine such as Minimongo. This accesses data through your publications, so will see exactly the data that you have published, no more no less. No selector is needed.
Example code:
postsIndex = new EasySearch.Index({
collection: Posts,
fields: ['name', 'tags', 'created_by_username'],
defaultSearchOptions: {
limit: 6
},
engine: new EasySearch.Minimongo() // search only on the client, so only published documents are returned
});
Alternatively you could use a server-side search engine such as MongoDB. In this case you should add a selector to control what data are returned.
Unfortunately I haven't been able to get selectors working with MongoDB. You can't use Meteor.userId() because the code runs on both server and client, and when I try the recipe for this in the documentation, I see an error on the server. Using Michel Floyd's construction, options.search.userId exists but is null. If I find out how to do it, I'll update this answer for completeness.

Tracking a tweeter hashtag (keyword) with stream API

I am trying to track all tweets by given hashtag or keyword. The problem is I can stream the tweets when I use a simple keyword like 'animal' but when I change it to say 'animal4666' then it doesn't work. No reply is received. I am using the code below.
twit.stream('statuses/filter', { track: 'animal4666' }, function(stream) {
stream.on('data', function(data) {
console.log(util.inspect(data));
});
});
I have made two tweets from different account like following:
'#animal4666 a'
'#animal4666 trying to find out what is going on?'
Above tweets are successfully retrieved using search API but because of the rate limitations on search API I need to use stream API so that i can check for new tweets every two seconds with node.js
The addon I am using of node.js: https://github.com/jdub/node-twitter
Can someone please help?
If you look the code of the library you are using, it seems that there is nothing potentially wrong
it only has a workaround when you pass an array in the track param, but is not the case
// Workaround for node-oauth vs. twitter commas-in-params bug
if ( params && params.track && Array.isArray(params.track) ) {
params.track = params.track.join(',')
}
So looking in to the official api docs for track method, I see two caveats that may are relevant.
Each phrase must be between 1 and 60 bytes, inclusive.
I think yours are shorter but is something to take in mind
And what I think is your real problem:
Exact matching of phrases (equivalent to quoted phrases in most search
engines) is not supported.
Punctuation and special characters will be considered part of the term
they are adjacent to. In this sense, "hello." is a different track
term than "hello". However, matches will ignore punctuation present in
the Tweet. So "hello" will match both "hello world" and "my brother
says hello." Note that punctuation is not considered to be part of a
#hashtag or #mention, so a track term containing punctuation will not match either #hashtags or #mentions.
You can check online your tweet text to see if it match here

Twitter search: OR with Tags - but how?

I cannot search the twitter API for tweets which contain one of multiple tags.
Like: q="#tag1 OR #tag2 OR #tag3"
If I leave away the hashes and only search for words, the OR-ing works. For tags they don't.
When I only use spaces, the search terms will be AND-ed, what shrinks the result...
I use the twitter4j library with:
Twitter rest = new TwitterFactory().getInstance();
Query query = new Query();
query.setQuery("#win | #fail");
QueryResult result = rest.search(query);
Isn't it possible, or didn't i use it correctly?
Might just be easier to use twitter's REST API. You'll want to use the search query. Here's an example search url searching for #LA, #NYC or #Boston. Note the spaces and #s are all URL encoded. Just pop a URL like that into a getJSON call like below and you can easily extract your values from the returned JSON object as in the example.
var requestedData = "http://search.twitter.com/search.json?q=%23LA%20OR%20%23NYC%20OR%20%23Boston%22&callback=?"
$.getJSON(requestedData,function(ob)
{
var firstTweet = ob.results[0].text;
var firstTweeter = ob.results[0].from_user;
}
From there it's just a matter of looping through your results and pulling the appropriate fields which are all outlined in the JSON file if you simply visit that example search link in your browser! I don't know this TwitterFactory API but its possible they haven't updated to Twitter's new API or they're just not URL encoding appropriately. Good luck!
Try to use OR operator instead of "|":
query.setQuery("#win OR #fail");
See available Twitter search API operators here:
Using the Twitter Search API

Resources