There's more going on in the functions than just this check (which is the only part of the function I needed help with hopefully) and I recorded the time for the entire function call. The only difference between the two sets of times I reported is the line I included above the times (map:keys...).
Using exists was even slower. So, perhaps there's something in how I'm using it - I haven't given you the whole function. Sorry if the subject was misleading, but in fact, I do want to be able to find a set of keys using this same technique (i.e., one of them) within another function. This is just the first way I need to use it when building the entire map. Thanks again, David -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Michael Blakeley Sent: Friday, August 02, 2013 10:57 AM To: MarkLogic Developer Discussion Subject: Re: [MarkLogic Dev General] finding a set of keys in map There's something wrong if either of those expressions takes 20-sec with 80 keys. But I think I misunderstood the output you wanted. The SMO will just return true or false, which is great if that's all you want. I was looking at the subject "finding a set of keys in map", which is what that predicate does. But if you only want a boolean result: exists(map:keys($map)[contains(., $v)]) That might help a bit, since exists() should be able to stop as soon as it finds a match. The SMO expression with op:equals probably does that too. With 10^6 keys I find that they perform about the same, and I can see the short-circuit happening in the profiler. declare variable $map := map:map() ; declare variable $v := 'ab' ; declare variable $start := () ; (1 to 1000000) ! xdmp:integer-to-hex(xdmp:random()) ! map:put($map, ., .), map:count($map), xdmp:set($start, xdmp:elapsed-time()), exists(map:keys($map)[contains(. ,$v)]), xdmp:elapsed-time() - $start, xdmp:set($start, xdmp:elapsed-time()), (map:keys($map) ! fn:contains(.,$v)) = true(), xdmp:elapsed-time() - $start, xdmp:elapsed-time() => 1000000 true PT0.655776S true PT0.669854S PT6.356527S Most of the time is spent building the map, but SMO takes about the same amount of time as the predicate. -- Mike On 2 Aug 2013, at 07:29 , "Steiner, David J. (LNG-DAY)" <[email protected]> wrote: > With two test run, the non-predicate seems faster, or as fast. Perhaps with > a lot more keys, there'll be a difference... > > At any rate, this is great! I appreciate it very much! > > > With ((map:keys($map) ! fn:contains(.,$v)) = fn:true()): > test1 (80 keys) > <qm:elapsed-time xmlns:qm="http://marklogic.com/xdmp/query-meters" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> > PT21.34633S > </qm:elapsed-time> > > test2 (16 keys) > <qm:elapsed-time xmlns:qm="http://marklogic.com/xdmp/query-meters" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> > PT0.554321S > </qm:elapsed-time> > > > With (map:keys($map)[contains(., $v)]): > test1 (80 keys) > <qm:elapsed-time xmlns:qm="http://marklogic.com/xdmp/query-meters" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> > PT21.449702S > </qm:elapsed-time> > > test2 (16 keys) > <qm:elapsed-time xmlns:qm="http://marklogic.com/xdmp/query-meters" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> > PT1.506917S > </qm:elapsed-time> > > -----Original Message----- > From: [email protected] > [mailto:[email protected]] On Behalf Of Michael > Blakeley > Sent: Friday, August 02, 2013 9:55 AM > To: MarkLogic Developer Discussion > Subject: Re: [MarkLogic Dev General] finding a set of keys in map > > I think you'd want a predicate rather than a SMO. This is an exhaustive > search, but it will probably be plenty fast because the map is already in > memory anyway. > > map:keys($m)[contains(., $substring)] > > Or use a regex via fn:matches, etc. If you really need wildcards rather than > regex, you could build a text node around each key and use cts:contains. > That's necessary because cts:contains expects nodes - but that will be a > little more expensive too. > > map:keys($m)[cts:contains(text { . }, $glob)] > > But if the keyset is large enough that a scan isn't practical, there may be > other options. If you have a pretty good idea of what wildcard patterns you > need, you might be able to change the way you build keys. For example you > could insert wildcarded keys that map to the right keys. > > If you know that the keys are based on a real element that has a range index, > you could use cts:element-value-match on that. But I think both of the > previous approaches are likely to be faster. > > -- Mike > > On 2 Aug 2013, at 06:40 , David Lee <[email protected]> wrote: > >> Its not highly efficient but since maps are internally hash-maps there is no >> wildcard indexing on them. >> You have to manually iterate the keys. >> This or something like it (by memory) should work >> >> (map:keys( $map ) ! fn:contains(.,"*wildcard")) = fn:true() >> >> >> >> >> >> --------------------------------------------------------------------- >> -------- >> David Lee >> Lead Engineer >> MarkLogic Corporation >> [email protected] >> Phone: +1 812-482-5224 >> Cell: +1 812-630-7622 >> www.marklogic.com >> >> >> From: [email protected] >> [mailto:[email protected]] On Behalf Of >> Steiner, David J. (LNG-DAY) >> Sent: Friday, August 02, 2013 9:34 AM >> To: MarkLogic Developer Discussion >> Subject: [MarkLogic Dev General] finding a set of keys in map >> >> Is there a way to find a group of map entries by "wildcarding" a key? >> >> Ideally, I'd like to say: map:contains($map, "*value-to-find") and get back >> "true" if any of my keys contain "value-to-find". >> >> Thanks, >> David >> _______________________________________________ >> General mailing list >> [email protected] >> http://developer.marklogic.com/mailman/listinfo/general > > _______________________________________________ > General mailing list > [email protected] > http://developer.marklogic.com/mailman/listinfo/general > _______________________________________________ > General mailing list > [email protected] > http://developer.marklogic.com/mailman/listinfo/general > _______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general
