Форум » [x]Harbour » Непонятки при отборе из базы ? » Ответить

Непонятки при отборе из базы ?

Andrey: Что то при отборе из базы двояться записи .... База проиндексирована по полю INET. Делаю так: [pre2]nInet := 0 aRec := {} ..... SELECT ZMAIN DbSetOrder(3) GOTO TOP dbSeek(nInet, .T. ) // Set softseek on DO WHILE !EOF() IF ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17") AADD( aRec, { ZMAIN->ID, ZMAIN->NNZ, RECNO() } ) ENDIF dbSkip(1) ENDDO MsgDebug("массив = ", aRec) [/pre2] Правлю базу, т.е. для ТРЕХ записей делаю ZMAIN->INET := 0 Вызываю эту функцию и она возвращает массив из 6 элементов !!! Почему ? 1 {56614, "622/03", 56614} 2 {56615, "623/03", 56615} 3 {56616, "624/03", 56616} 4 {56614, "622/03", 56614} 5 {56615, "623/03", 56615} 6 {56616, "624/03", 56616} Что не так делаю ?

Ответов - 37, стр: 1 2 All

rvu: Проиндексированы названия фирм. Ищу с помощью DBSEEK() или SEEK. Кстати, между ними разница есть? Что лучше использовать? Есть название фирмы "ATOMIC Austria GmbH". По "ATOMIC Austria GmbH" найдет. По "ATOMIC" тоже найдет. А вот "Austria" не найдет. Есть какой-нибудь способ найти по слову в середине или в конце? И прописные и строчные буквы важны. Как-то можно это игнорировать?

Dima: rvu пишет: Как-то можно это игнорировать? UPPER в ключе индекса rvu пишет: Есть какой-нибудь способ найти по слову в середине или в конце? Locate по вхождению Функции из цикла *wild rvu пишет: Ищу с помощью DBSEEK() или SEEK. Кстати, между ними разница есть? Что лучше использовать? Смотрим Std.ch [pre2] #ifdef HB_COMPAT_C53 #command SEEK <exp> [<soft: SOFTSEEK>] [<last: LAST>] => ; dbSeek( <exp>, iif( <.soft.>, .T., NIL ), iif( <.last.>, .T., NIL ) ) #else #command SEEK <exp> [<soft: SOFTSEEK>] => ; dbSeek( <exp>, iif( <.soft.>, .T., NIL ) ) #endif [/pre2]

SergKis: rvu пишет Есть какой-нибудь способ найти по слову в середине или в конце? см. http://www.kresin.ru/hrbfaq_3.html#Doc13_14 3.13.14 HiPer-SEEK (Fast Text Search) rvu gbitn Кстати, между ними разница есть? Что лучше использовать? см. std.ch команда SEEK rvu пишет Есть какой-нибудь способ найти по слову в середине или в конце? перебором с проверкой на вхождение. Пример[pre2] aFnd := {"ATOMIC Austria GmbH", "Austria", "GmbH"} // что ищем aRec := {} // результат GO TOP DO WHILE ! eof() FOR EACH cN IN aFnd IF cN $ in->FirmName // можно приводить к upper() или lower() AAdd(aRec, RecNo()) ENDIF NEXT SKIP ENDDO [/pre2]


Dima: еще https://cloud.mail.ru/public/JXdG/33Y1EjPMd

rvu: Dima пишет: UPPER в ключе индекса А как это сделать?

rvu: SergKis пишет: перебором с проверкой на вхождение. Пример aFnd := {"ATOMIC Austria GmbH", "Austria", "GmbH"} // что ищем aRec := {} // результат GO TOP DO WHILE ! eof() FOR EACH cN IN aFnd IF cN $ in->FirmName // можно приводить к upper() или lower() AAdd(aRec, RecNo()) ENDIF NEXT SKIP ENDDO Не в индексном файле искать? Это очень долго будет.

Andrey: rvu пишет: Проиндексированы названия фирм. Когда делаешь индекс, то ставь типа такого: UPPER(in->FirmName) Какое кол-во записей для поиска ? Если тысяч 10-15, то это быстро будет.

rvu: Andrey пишет: Какое кол-во записей для поиска ? Если тысяч 10-15, то это быстро будет. Перебором базы по строчкам? Увы, у нас счет на миллионы записей. И названия фирм это самое малое, есть еще тексты, в которых тоже нужно отдельные слова искать.

Andrey: Ну тогда нужно смотреть что советовал SergKis !

rvu: Andrey пишет: Ну тогда нужно смотреть что советовал SergKis ! Я так понимаю, речь про SergKis пишет: HiPer-SEEK ?

SergKis: rvu пишет Не в индексном файле искать? Это очень долго будет Если не хотите использовать HiPer-SEEK, создайте и ведите базу, где все слова из наименования перенесены в одно поле, т.е. dbf структура {{"Name", "C", 30, 0},{"ID", "N", 10, 0}, {"RECN", "N",10,0}} Преобразуйте поле с наим. фирмы (можно добавить и ИНН ...) примерно так[pre2] FOR EACH cT IN hb_Atokens(alltrim(IN->FirmName)+' '+alltrim(IN->INN), ' ') IF ! empty(cT) dbAppend() OU->NAME := cT OU->ID := IN->ID OU->RECN := IN->(RecNo()) ENDIF NEXT INDEX ON upper(NAME) TAG NAME ... Эту базу ведете совместно с ведением основной, но поиск делаете по созданной выше, используя scope Все будет летать [/pre2]

rvu: SergKis пишет: Если не хотите использовать HiPer-SEEK Почему не хочу? Надо попробовать. Мне кажется, это для меня вообще единственный вариант. SergKis пишет: создайте и ведите базу, где все слова из наименования перенесены в одно поле, т.е. dbf структура {{"Name", "C", 30, 0},{"ID", "N", 10, 0}, {"RECN", "N",10,0}} Это не спасет. Там еще и тексты, иногда большие. И в них нужно искать отдельные слова.

SergKis: rvu пишет Это не спасет. Там еще и тексты, иногда большие. И в них нужно искать отдельные слова. Никто не мешает добавить поле TEXT в создаваемую базу и фильтровать по доп. условию. Или - получив список RecNo в массиве, ставить BM filter на осн. базу и делать доп. поиск - сделав SeT RELATION ID TO <осн. база>, проделать доп. поиски Такая схема работала до появления HiPer-SEEK еще со времен Summer 87

rvu: SergKis пишет: Никто не мешает добавить поле TEXT в создаваемую базу и фильтровать по доп. условию. Как я понял DBSEEK() не ищет отдельные слова внутри текста. Не делать же поля на каждое слово в тексте.

SergKis: rvu пишет Как я понял DBSEEK() не ищет отдельные слова внутри текста. Не делать же поля на каждое слово в тексте. В показанной схеме нет использования dbseek(), используем scope на слово\часть и по полученному списку работаем Если в основной базе есть M поля с текстом, то из них можно выбрать ключевые и записать в поле TEXT для поска aFnd := {""...", "..."} aTxt := {""...", "..."} hRec := hb_Hash() SET SCOPE TO "GmbH", "GmbH" SET RELATION ID TO BASE // для поиска в осн. базе, если надо GO TOP DO WHILE ! eof() FOR EACH cN IN aFnd IF cN $ BASE->NOTE hb_HSet(hRec, ID, RECN) ENDIF NEXT FOR EACH cT IN aTxt IF cT $ TEXT hb_HSet(hRec, ID, RECN) ENDIF NEXT SKIP ENDDO SET SCOPE TO в hRec будет список ID и соотв. RecNo осн. базы для дальнейшего исп. Можно сбросить в MEMIO и дать на Browse, связав с основной базой. С HiPer-SEEK будет похожая работа, только по правилам (ф-ям HiPer-SEEK)

SergKis: rvu пишет А вы им пользовались? Давно с SixNsx драйвером в 5.2, но потом вернулся на схему из Summer 87 пример [pre2] LOCAL cExpr := "test->FIRST + test->LAST + test->STREET + test->CITY" LOCAL bExpr := &( "{||" + cExpr + "}" ) LOCAL cVal := "John", h := 0, nRec := 0 CLS USE test EXCL IF !file("TEST.HSX") ? "Building HiPer-SEEK Index..." h := hs_Index( "TEST.HSX", cExpr, 2 ) ELSE h := hs_Open( "TEST.HSX", 8, 1 ) ENDIF hs_Set( h, cVal ) nRec := hs_Next( h ) DO WHILE nRec > 0 dbGoto( nRec ) IF hs_Verify( bExpr, cVal ) ? nRec ENDIF nRec := hs_Next( h ) ENDDO hs_Close( h ) [/pre2]

rvu: SergKis, спасибо, понял в чем было дело, вроде, заработало.



полная версия страницы