Searching with multiple keys and "begins with" - mongodb

What's the best way to perform the following type of search in a collection named "things":
mylist = ['lak', 'dodg', 'ang']
and the return could be:
["lake", "Lakers", "laky", "dodge", "Dodgers", "Angels", "angle"]
Would I need to perform a separate query for each?

To do this you want to use the mongodb command $in to search for all things that match with something in your array.
The command you would use would be:
db.things.find( {name: { $in: mylist }} )
But for this to work you want to be using regular expressions in your array, so you can either define them in the array, or if you want to maintain strings then the best thing to do it probably just create another array and loop through and create regex from the strings.
mylist = [/^lak/i, /^dodg/i, /^ang/i]
The ^ making it match only if it begins with the value, and the i at the end to make the search case insensitive.

Related

Building $in array containing both strings and regex patterns

I have a Mongo collection where every document in the collection has a sources array property. Searches on this property can be a combination of exact matches and regex. For example, when using Mongo shell, the query below searches for documents with source='gas valves' OR 'hose' is contained in source item. This works just as I expect
db.notice.find({sources:{$in:[/\bhose/i,'gas valves']}})
Things get a little trickier in mgo. Because some items in the $in array can be regex, and the others strings - the only way I have figured to make a query is by using $or:
var regEx []bson.RegEx
var matches []string
// do stuff to populate regEx and matches
filter["$or"] = []bson.M{
{"sources":bson.M{"$in":regEx}},
{"sources":bson.M{"$in":matches}},
}
Is there some way I could construct one slice with both regex and string to use with $in - eliminating the need for the $or
Use []interface{}:
matches := []interface{}{
bson.RegEx{"jo.+", "i"},
"David",
"Jenna",
}
db.C("people").Find(bson.M{"name": bson.M{"$in": matches}})
[] means slice and interface{} means any type. Put together, []interface{} is a slice of any type.

How to find on the basis of case-insensitive value in MongoDB PHP?

How to find on the basis of case-insensitive value in MongoDB PHP?
I am using below lines of code
$query = ['VehicleNumber' => $arg];
$cursor = $this->collection->find($query);
I want to find the data on the basis of VehicleNumber but it should be able find the data on the basis of case insensitive arg. For e.g if there are data in the table with vehicle numbers like JK AB123, JK DE245 etc. Now if arg contains jk Ab123, it should be able to find that data.
Please help !!!
You should use \MongoDB\BSON\Regex, with the "i" flag (Case insensitivity to match upper and lower cases).
You should also escape the string to not match any regex special characters; for this you can use preg_quote.
$query = ['VehicleNumber' => new \MongoDB\BSON\Regex( preg_quote($arg),"i")];
You can use $regex for find case sensitive values.
db.col.find({"VehicleNumber": { "$regex": /^jk Ab123/i } })

swift, how i find the letter that i want in sentence or word?

I want to find letter in variable a,
what is code for searching method?
Example:
var a = ["coffee","juice","water"]
search letters is "co"
searching method's result is "cofee",
what is searching method?
First you need to iterate over an array and select elements which match some condition, there's a filter method for that. In this case you need to check if a word contains some string, so use containsString.
a.filter { $0.containsString("un") }

Sort matches by closer to the beginning of the string

There is a table, which contains site URLs.
I want to sort Sphinx results in a way: "the closer keyword to the beginning of string - the more relevant"
"foobar.com, barfoo.com, barbarfoo.com" is correct result set for keyword "foo"
I have tried :
$s = new SphinxClient;
$s->setServer("localhost", 9312);
$s->SetMatchMode(SPH_MATCH_ALL);
$s->SetSortMode(SPH_SORT_RELEVANCE);
$s->SetFieldWeights(array(
'id' => 0,
'url' => 1000,
));
$result = $s->query("foo");
Unfortunately I get result, that sorted by id.
Hmm, dont think sphinx can do that directly. There are various ranking factors but all based on words.
Can match part words using the 'min_prefix_len', but cant get 'where in the word' the match happens, to be able to rank by it.
The only way may be able to get to work with sphinx, would be to use wordbreaker
http://sphinxsearch.com/blog/2013/01/29/a-new-tool-in-the-trunk-wordbreaker/
to index your domains names as seperate words. Hoping that your domains would be split correctly at "foo bar com", "bar foo com", "bar bar foo com" - which then could rank by word position, eg min_hit_pos
http://sphinxsearch.com/docs/current.html#field-factors

Does CoffeeScript have something like wildcard binding in destructing assignment?

In Scala, I can do things like:
val List(first, _, third) = List(1, 2, 3)
// first = 1
// third = 3
I currently have some CoffeeScript code in which I'm also not interested some elements in the array. Ideally, I would like to use a wildcard, like I'm doing in Scala.
[first, _, third] = [1, 2, 3]
Now, this does work, but it also adds this assignment:
_ = 2
… which is clearly not what I want. (I'm using underscore.) What's the preferred way of ignoring values in the array?
By the way, I'm using this for regular expression matching; the regular expression I'm using has optional groups that are really there for matching only, not to get any real data out.
match = /^(([a-z]+)|([0-9]+)) (week|day|year)(s)? (before|after) (.*)$/.exec str
if match?
[__, __, text, number, period, __, relation, timestamp] = match
…
In your specific case you could bypass the whole problem by using non-capturing groups in your regex:
(?:x)
Matches x but does not remember the match. These are called non-capturing parentheses. The matched substring can not be recalled from the resulting array's elements [1], ..., [n] or from the predefined RegExp object's properties $1, ..., $9.
If I'm reading your code right, you'd want:
/^(?:([a-z]+)|([0-9]+)) (week|day|year)(?:s)? (before|after) (.*)$/
You could also replace (?:s)? with s? since there's no need to group a single literal like that:
/^(?:([a-z]+)|([0-9]+)) (week|day|year)s? (before|after) (.*)$/
In either case, that you leave you with:
[__, text, number, period, relation, timestamp] = match
You could use an array slice to get rid of the leading __:
[text, number, period, relation, timestamp] = match[1..]
The match[1..] is a hidden call to Array.slice since the destructuring isn't smart enough (yet) to just skip match[0] when breaking match up. That extra method call may or may not matter to you.
There is no way to have wildcard assignments like that. You could use a double underscore __, like this
[first, __, third] = [1, 2, 3]
Personally, I would name the second variable in a way that makes sense, even if it is not used afterwards.