FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Wildcard Search
Posts: 83
Joined: Mon Oct 17, 2005 10:33 AM
Wildcard Search
Posted: Fri May 01, 2009 05:05 PM

Hi,

I have strings like
"2007/14/0001"
"2004/14/0877"
"2008/15/0056"
...
in a very large database.
I need to find all fields containing "/14/" not using the locate command, because it is too slow.
Does anyone have a fast solution for a wildcard search, something like seek "/14/" ?

Thank for any suggestions!
Dietmar

Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Wildcard Search
Posted: Fri May 01, 2009 05:49 PM
Dietmar:

If you are using xHarbour pls have a look at WildMatch() function.

Here is an example

Code (fw): Select all Collapse
cFiltro := "*" + ALLTRIM(cFiltro) + "*"
(cProducto)->(DBSETFILTER({||  WildMatch(cFiltro, (cProducto)->PRO_DES,(.T.)) },;                      "WildMatch(cFiltro, (cProducto)->PRO_DES,(.T.))" ))

Best regards
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Wildcard Search
Posted: Fri May 01, 2009 07:02 PM
Hello Dietmar,

I use this function:
Code (fw): Select all Collapse
STATIC aKunden := {}

function SearchFile( suchbeg )
   local nLocation, cData
   local nOffset := 0
   local cDBF    := (  "kunden.dbf" )
   local nPos    := 0

   suchbeg := ALLTRIM(Upper(suchbeg))
   cData   := Upper(MemoRead( cDBF ))

   if Len(cData ) < 1
      MsgInfo("Not Data to Search","File Error")
      Return Nil
   endif

   nOffset := 0
   
   do while .t.
       nPos := INT( AT( suchbeg, cData, nOffset ))    
      
        nLocation := INT( ( nPos - Header() ) / RecSize() ) + 1
        nOffset   := Header() + nLocation * RecSize() + RecSize()
      
      if nPos > 0 .and. nPos <  Header()  
      else
          if nLocation < 1
             Exit
          else
             select kunden
             goto  nLocation
             if DELETED() = .F.
                aAdd( aKunden, getrec() )
               endif
          endif
            
        endif
   
   enddo

Return Nil
//------------------------------------------------------------------




Best regards,
Otto
Posts: 842
Joined: Mon Oct 10, 2005 01:29 PM
Re: Wildcard Search
Posted: Sun May 03, 2009 07:22 AM

Hello

You cann use temporary index , it is very faster .

index on field->N1 TAG I_TEMP FOR &(ff) TO TEMP TEMPORARY

TEMPORARY
If this option is specified, a temporary index is created which is automatically destroyed when the index is closed.

TO TEMP
The temporary index may be created in memory only .

Maurizio

Posts: 169
Joined: Mon Feb 25, 2008 02:42 AM
Re: Wildcard Search
Posted: Sun May 03, 2009 10:35 AM

Mr. Maurizio

Do you have complete sample ?

Thanks

Regards
Fafi

Posts: 842
Joined: Mon Oct 10, 2005 01:29 PM
Re: Wildcard Search
Posted: Mon May 04, 2009 06:56 AM

Hello
use clients

index on field->ADRESS TAG ADR TO TEMP TEMPORARY FOR field->COUNTRY == "USA"
Browse()

use

Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Wildcard Search
Posted: Mon May 04, 2009 07:28 AM

Hello Maurizio,

Thank you for sharing.

Is the index after you created automatically opened or do you have to open the
index file.
If you have in your example a clients.cdx do you have to close this before you create the temporary index file or do they coexistent
How to you change the index order.

First you have for example:

Use clients new
Clients-cdx with tag name, town, etc. is opened automatically.

How do you go ahead with your example?

Thanks in advance
Otto

Posts: 842
Joined: Mon Oct 10, 2005 01:29 PM
Re: Wildcard Search
Posted: Mon May 04, 2009 01:02 PM

Hello Otto

The index is automatically opened , and you don't have to close the previous index .

// How do you go ahead with your example?

If the natural index name is CLIENT.CDX :

set index to CLIENT

Regards MAurizio

Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Wildcard Search
Posted: Mon May 04, 2009 05:10 PM

xHarbour's OrdWildSeek( <cWildSeekExprn> )

Example:
OrdWildSeek( "/14/" )

Regards



G. N. Rao.

Hyderabad, India
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: Wildcard Search
Posted: Tue May 05, 2009 05:24 AM

I don't know whether the Soft seek solution work or not, Anyway it is just a hint
You need to have DBF indexed on the desired field.

Set Soft On
Seek "/14/"
Set Soft Off
Do While SubStr(Alias->FieldName,6,2) == "14"
....
Skip
Enddo

Mr.Rao's solution using xHarbours' OrdWildSeek( "/14/" ) seems to be a good one.

Regards

Anser

Posts: 41
Joined: Thu Dec 22, 2005 07:39 AM
Re: Wildcard Search
Posted: Tue May 05, 2009 06:03 AM
Hello!
This is a several solutions from xHarbour "TESTS":
1.
Code (fw): Select all Collapse
cRegex:="*/14/*"
cRegex:=HB_REGEXCOMP(cRegex)
dbgotop()
while !eof()
   if ordkeyval() HAS cRegEx
      // TA-DA!!! We got it!!!
      ?ordkeyno()
   endif
   dborderinfo(DBOI_SKIPREGEX,,,cRegex)
enddo

2.
Code (fw): Select all Collapse
cPattern:="*/14/*"
nSec:=secondscpu()
dbgotop()
if !eof() .and. ! WildMatch(cPattern, ordkeyval())
   dborderinfo(DBOI_SKIPWILD,,,cPattern)
endif
while !eof()
   if WildMatch(cPattern, ordkeyval())
      // TA-DA!!! We got it!!!
      ?ordkeyno()
   endif
   dborderinfo(DBOI_SKIPWILD,,,cPattern)
enddo


In both cases you have to make the index on your field.
Best regards!

Sergey (Loach) Abelev

fwh 9.04/xHarbour 1.2.1 (Rev. 6406)/Bcc55
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Wildcard Search
Posted: Tue May 05, 2009 06:43 AM
Mr.Rao's solution using xHarbours' OrdWildSeek( "*/14/*" ) seems to be a good one.

Mr Dietmar wanted all rows matching this criteria. In that case Mr Armando's solution of setting filter is more appropriate.

Yes, like many other friends suggested, there are many other solutions. But Mr Armando's recommendation is simple and fast enough.

Relating to the functions OrdWildSeek() and WildMatch() I have one question:
I am aware that OrdWildSeek() works both in Harbour and xHarbour.
But for me WildMatch() is working only in xHarbour and not in Harbour. Does any one know an equivalent function in Harbour?
Regards



G. N. Rao.

Hyderabad, India
Posts: 41
Joined: Thu Dec 22, 2005 07:39 AM
Re: Wildcard Search
Posted: Tue May 05, 2009 07:04 AM

Mr. nageswaragunupudi.
For me "setfilter" is too slow (if you want to browse the data), especially with a very large databases. Much more effective to create the CUSTOM INDEX from the array of finded records.
PS. About your question, sorry, I use only xHarbour...

Best regards!

Sergey (Loach) Abelev

fwh 9.04/xHarbour 1.2.1 (Rev. 6406)/Bcc55
Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Wildcard Search
Posted: Tue May 05, 2009 07:08 AM

Hello Mr. Rao,

would you be so kind to advice me how to handle lower and upper case with OrdWildSeek.
I would need a search independent of the case.

Thanks in advance
Otto

Posts: 6984
Joined: Fri Oct 07, 2005 07:07 PM
Re: Wildcard Search
Posted: Tue May 05, 2009 07:26 AM
Hello Mr. Rao,

The search function I suggested above is build after an advice from Antonio:
http://forums.fivetechsupport.com/viewtopic.php?f=3&t=968&p=3824&hilit=RecSize#p3824

Jeff,

Some years ago we helped a company to test several third party tools for such purpouse and finally implemented our own solution to make the fastest search on all fields of a DBF.

We found with great surprise that the solution was to open the DBF as a standard file with FOpen(), read a bunch of bytes in memory and perform a simple At() to locate a string. Once found, you substract the DBF header length, then divide the offset by the record size and you get the record number. At() is an extremelly fast function as it is directly performed by the processor.

These days that we use 32 bits flat memory, I guess there is no need to use a bunch of bytes, so the entire DBF may be loaded in memory doing a MemoRead() of the DBF file, or several bunchs if it is too large, so the code may get simpler.

We compared this way with other available third party tools, and we found that ours was the fastest one

Its worth to try it.


I would like to test OrdWildSeek and compare speed.
Do you open the dbf – file with memoread ?
I can’t imagine that skipping through the file record by record is the solution.
Do you have some more infos.

Thanks in advance
Otto