Собственные типы индексов в СУБД caché

17
Собственные типы индексов (они же функциональные индексы)

Upload: intersystems-cee

Post on 15-Apr-2017

102 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Собственные типы индексов в СУБД Caché

Собственные типы индексов (они же функциональные индексы)

Page 2: Собственные типы индексов в СУБД Caché

Конечный результат

Property A As %String;

Property B As %String;

Index someind On (A,B) As CustomPackage.CustomIndex;

Page 3: Собственные типы индексов в СУБД Caché

Собственно квадродерево

Class SpatialIndex.Indexer {

Method %OnNew(indexGlobal As %String) As %Status

Method Insert(x As %Float, y As %Float, id As %String)

Method Delete(x As %Float, y As %Float, id As %String)

}

Page 4: Собственные типы индексов в СУБД Caché
Page 5: Собственные типы индексов в СУБД Caché
Page 6: Собственные типы индексов в СУБД Caché

ClassMethod InsertIndex(pID, pArg... As %Binary) [ CodeMode = generator] {

if %mode'="method" {

set IndexGlobal = ..IndexLocation(%class,%property)

$$$GENERATE($C(9)_"set indexer = " _

"##class(SpatialIndex.Indexer).%New($Name("_IndexGlobal_"))")

$$$GENERATE($C(9)_"do indexer.Insert(pArg(1),pArg(2),pID)")

}

}

Class SpatialIndex.Index Extends %Library.FunctionalIndex

Page 7: Собственные типы индексов в СУБД Caché

Пример использования

Class SpatialIndex.Test Extends %Persistent {

Property Name As %String(MAXLEN = 300);

Property Latitude As %String;

Property Longitude As %String;

Index coord On (Latitude, Longitude) As SpatialIndex.Index;

}

Page 8: Собственные типы индексов в СУБД Caché

SpatialIndex.Test.1.INT

zcoordInsertIndex(pID,pArg...) public {

set indexer =

##class(SpatialIndex.Indexer).%New($Name(^SpatialIndex.TestI("coord")))

do indexer.Insert(pArg(1),pArg(2),pID)

}

zcoordUpdateIndex(pID,pArg...) public {

set indexer =

##class(SpatialIndex.Indexer).%New($Name(^SpatialIndex.TestI("coord")))

do indexer.Delete(pArg(3),pArg(4),pID)

do indexer.Insert(pArg(1),pArg(2),pID)

}

Page 9: Собственные типы индексов в СУБД Caché

SpatialIndex.Test.1.INT

%SaveData(id) {

if insert {

// ...

do ..coordInsertIndex(id,i%Latitude,i%Longitude,"")

// ...

} else {

// ...

do ..coordUpdateIndex(id,i%Latitude,i%Longitude,zzc27v3,zzc27v2,"")

// ...

}

}

Page 10: Собственные типы индексов в СУБД Caché

Так данные индекса выглядят в глобале

USER>zwrite ^SpatialIndex.TestI("coord")

^SpatialIndex.TestI("coord"," ")=$lb(-180,-90,180.0001,90.0001,0,0)

...

^SpatialIndex.TestI("coord"," 30")=$lb(.00005,.00005,90.000075,45.000075,0,0)

^SpatialIndex.TestI("coord"," 300")=$lb(.00005,.00005,45.0000625,22.5000625,1,0)

^SpatialIndex.TestI("coord"," 301")=$lb(45.0000625,.00005,90.000075,22.5000625,0,0)

^SpatialIndex.TestI("coord"," 3010")=$lb(45.0000625,.00005,67.50006875,11.25005625,1,0)

^SpatialIndex.TestI("coord"," 3011")=$lb(67.50006875,.00005,90.000075,11.25005625,1,0)

^SpatialIndex.TestI("coord"," 3012")=$lb(45.0000625,11.25005625,67.50006875,22.5000625,0,0)

^SpatialIndex.TestI("coord"," 30120")=$lb(45.0000625,11.25005625,56.250065625,16.875059375,1,0)

...

Page 11: Собственные типы индексов в СУБД Caché

А как же запросы?

SELECT *

FROM SpatialIndex.Test

WHERE %ID %FIND search_index(coord, 'window',

'minx=56,miny=56,maxx=57,maxy=57')

Page 12: Собственные типы индексов в СУБД Caché

Снова SpatialIndex.Indexer

ClassMethod Find(queryType As %Binary, queryParams As %String) As

%Library.Binary [ CodeMode = generator, SqlProc ]

{

if %mode'="method" {

set IndexGlobal = ..IndexLocation(%class,%property)

$$$GENERATE($C(9)_"set result = ##class(SpatialIndex.SQLResult).%New()")

$$$GENERATE($C(9)_"do result.PrepareFind($Name("_IndexGlobal_"),

queryType, queryParams)")

$$$GENERATE($C(9)_"quit result")

}

}

search_index(coord, 'window', 'minx=56,miny=56,maxx=57,maxy=57')

Page 13: Собственные типы индексов в СУБД Caché

Метод, сгенерированный в SpatialIndex.Test.1.INT

zcoordFind(queryType,queryParams) public { Set:'$isobject($get(%sqlcontext)) %sqlcontext=##class(%Library.ProcedureContext).%New()

set result = ##class(SpatialIndex.SQLResult).%New()

do result.PrepareFind($Name(^SpatialIndex.TestI("coord")), queryType,

queryParams)

quit result }

search_index(coord, 'window', 'minx=56,miny=56,maxx=57,maxy=57')

Page 14: Собственные типы индексов в СУБД Caché

Class SpatialIndex.SQLResult Extends %SQL.AbstractFind

Property ResultBits [ MultiDimensional, Private ];

Method PrepareFind(indexGlobal As %String, queryType As %String, queryParams As %Binary) As %Status { // … }

Method NextChunk(ByRef pChunk As %Integer = "") As %Binary { set pChunk = $order(i%ResultBits(pChunk),1,tBits) quit:pChunk="" "" quit tBits }

Method ContainsItem(pItem As %String) As %Boolean { set tChunk = (pItem\64000)+1, tPos=(pItem#64000)+1 quit $bit($get(i%ResultBits(tChunk)),tPos) }

Page 15: Собственные типы индексов в СУБД Caché

В итоге запросы выглядят так:

SELECT *

FROM SpatialIndex.Test

WHERE %ID %FIND search_index(coord,'radius','x=55,y=55,radiusX=2,radiusY=2') and name %StartsWith 'Z'

Page 16: Собственные типы индексов в СУБД Caché

Параметр size предиката %FIND

SELECT *

FROM SpatialIndex.Test

WHERE name %startswith 'za'

and %ID %FIND

search_index(coord,'radius','x=55,y=55,radius=2')

size ((10))

Page 17: Собственные типы индексов в СУБД Caché

Спасибо. Вопросы?

http://habrahabr.ru/company/intersystems/blog/272689/