Skip to content

Commit

Permalink
moved date range search into wdt module (step 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
peterstadler committed Sep 5, 2017
1 parent 292ead5 commit 65e46af
Show file tree
Hide file tree
Showing 5 changed files with 420 additions and 37 deletions.
3 changes: 2 additions & 1 deletion api/v1/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"in": "query",
"description": "The min date to search for",
"type": "string",
"default": "1786-11-18",
"format": "date",
"required": true
},
Expand All @@ -129,7 +130,7 @@
"description": "The max date to search for",
"type": "string",
"format": "date",
"required": true
"required": false
},
{
"$ref": "#/parameters/docTypeParam"
Expand Down
2 changes: 1 addition & 1 deletion modules/api.xqm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ declare function api:documents($model as map()) {
:)

declare function api:documents-findByDate($model as map()) {
let $documents := for $docType in api:resolve-docTypes($model) return wdt:lookup($docType, core:getOrCreateColl($docType, 'indices', true()))?filter-by-date($model?fromDate, $model?toDate) (:query:exact-date(xs:date($model('date')), $docType):)
let $documents := for $docType in api:resolve-docTypes($model) return wdt:lookup($docType, core:getOrCreateColl($docType, 'indices', true()))?filter-by-date($model?fromDate, $model?toDate)
return
api:document(api:subsequence($documents, $model), $model)
};
Expand Down
20 changes: 0 additions & 20 deletions modules/query.xqm
Original file line number Diff line number Diff line change
Expand Up @@ -261,23 +261,3 @@ declare function query:contributors($doc as document-node()?) as xs:string* {
return
$contributors ! data(.)
};

(:~
: Search for exact dates within collections
: This function should probably be moved into the wdt module sometimes …
~:)
declare function query:exact-date($dates as xs:date*, $docType as xs:string) as document-node()* {
let $stringDates := $dates ! string(.) (: Need to do a string comparison to boost index performance :)
return
switch($docType)
case 'writings' case 'letters' case 'diaries' return
let $normDates := norm:get-norm-doc($docType)//norm:entry[. = $stringDates] ! core:doc(./@docID)
let $otherHits := core:getOrCreateColl($docType, 'indices', true())//tei:date[@when = $stringDates]/root()
return
(: pushing the normdates to the top of the result set :)
($normDates, $otherHits except $normDates)
case 'personsPlus' return
core:getOrCreateColl('persons', 'indices', true())//tei:date[@when = $stringDates]/root() |
core:getOrCreateColl('orgs', 'indices', true())//tei:date[@when = $stringDates]/root()
default return core:getOrCreateColl($docType, 'indices', true())//tei:date[@when = $stringDates]/root()
};
29 changes: 16 additions & 13 deletions modules/search.xqm
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,8 @@ declare %private function search:fulltext($searchString as xs:string, $filters a
declare %private function search:exact-date($dates as xs:date*, $filters as map(), $docType as xs:string) as map(*)* {
let $coll :=
if(count(map:keys($filters)) gt 0) then search:filter-result(core:getOrCreateColl($docType, 'indices', true()), $filters, $docType)
else ()
let $date-search := query:exact-date($dates, $docType)
let $docs :=
if($coll) then $coll intersect $date-search
else $date-search
else core:getOrCreateColl($docType, 'indices', true())
let $docs := wdt:lookup($docType, $coll)?filter-by-date($dates[1], $dates[2])
return
$docs ! map { 'doc' := . }
};
Expand Down Expand Up @@ -277,14 +274,19 @@ declare %private function search:filter-result($collection as document-node()*,
let $filter := map:keys($filters)[1]
let $filtered-coll :=
if($filter) then
if($filter = ('fromDate', 'toDate', 'undated')) then search:date-filter($collection, $docType, $filters)
if($filter = ('undated')) then ()
else if($filter = ('fromDate', 'toDate')) then wdt:lookup($docType, $collection)?filter-by-date(try {$filters?fromDate cast as xs:date} catch * {()}, try {$filters?toDate cast as xs:date} catch * {()} )
else if($filter = 'textType') then search:textType-filter($collection, $filters)
else if($filter = 'hideRevealed') then search:revealed-filter($collection, $filters)
else query:get-facets($collection, $filter)[range:contains(.,$filters($filter))]/root()
else $collection
let $newFilter :=
try { map:remove($filters, $filter) }
catch * {map:new()}
let $newFilter :=
if($filter = ('fromDate', 'toDate')) then
try { map:remove(map:remove($filters, 'toDate'), 'fromDate') }
catch * {()}
else
try { map:remove($filters, $filter) }
catch * {map:new()}
return
if(exists(map:keys($newFilter))) then search:filter-result($filtered-coll, $newFilter, $docType)
else $filtered-coll
Expand All @@ -294,14 +296,14 @@ declare %private function search:filter-result($collection as document-node()*,
: Helper function for search:filter-result()
: Applies chronological filter 'fromDate' and 'toDate'
~:)
declare %private function search:date-filter($collection as document-node()*, $docType as xs:string, $filters as map(*)) as document-node()* {
(:declare %private function search:date-filter($collection as document-node()*, $docType as xs:string, $filters as map(*)) as document-node()* {
let $filter := map:keys($filters)[1]
return
switch($docType)
case 'biblio' return
if ($filter = 'undated') then ($collection intersect core:undated($docType))/root()
else if ($filter = 'fromDate') then (
(: checking only the year for the lower threshold otherwise we'll miss date=1810 when checking 1810-01-01 :)
(\: checking only the year for the lower threshold otherwise we'll miss date=1810 when checking 1810-01-01 :\)
$collection//tei:date[range:field-ge('date-when', substring($filters($filter), 1, 4))] |
$collection//tei:date[range:field-ge('date-notBefore', substring($filters($filter), 1, 4))] |
$collection//tei:date[range:field-ge('date-notAfter', substring($filters($filter), 1, 4))] |
Expand Down Expand Up @@ -336,7 +338,7 @@ declare %private function search:date-filter($collection as document-node()*, $d
)[parent::tei:correspAction]/root()
case 'news' return
if ($filter = 'undated') then ($collection intersect core:undated($docType))/root()
(: news enthalten dateTime im date/@when :)
(\: news enthalten dateTime im date/@when :\)
else if ($filter = 'fromDate') then $collection//tei:date[substring(@when,1,10) >= $filters($filter)][parent::tei:publicationStmt]/root()
else $collection//tei:date[substring(@when,1,10) <= $filters($filter)][parent::tei:publicationStmt]/root()
case 'persons' case 'orgs' return ()
Expand All @@ -360,6 +362,7 @@ declare %private function search:date-filter($collection as document-node()*, $d
case 'places' return ()
default return $collection
};
:)

(:~
: Helper function for search:filter-result()
Expand Down Expand Up @@ -430,7 +433,7 @@ declare %private function search:get-latest-date($docType as xs:string, $cacheKe
(:~
: Read query string and parameters from URL
:
: @return a map with sanitized query string, parameters and recognized dates (via PDR web service)
: @return a map with sanitized query string, parameters and recognized dates
~:)
declare %private function search:prepare-search-string() as map(*) {
let $query-docTypes := request:get-parameter('d', 'all') ! str:sanitize(.)
Expand Down
Loading

0 comments on commit 65e46af

Please sign in to comment.