Getting information from matching records
The fetch method
The Module
class fetch method is used to get
information from the matching records once the search of a module has been run.
The server maintains the set of matching records in a list and the fetch
method can be used to retrieve any information from any contiguous block of
records in the list.
The simplest form of the fetch
method takes four arguments:
flag
offset
Together the
flag
andoffset
arguments define the starting position of the block of records to be fetched. Theflag
argument is aString
and must be one of:start
current
end
The
start
andend
flags refer to the first record and the last record in the matching set. Thecurrent
flag refers to the position of the last record fetched by the previous call to thefetch
method. If thefetch
method has not been called,current
refers to the first record in the matching set.The
offset
argument is anint
. It adjusts the starting position relative to the value of theflag
argument. A positive value foroffset
specifies a start after the position specified byflag
and a negative value specifies a start before the position specified byflag
.For example, calling
fetch
with aflag
ofstart
" andoffset
of 3 will return records starting from the fourth record in the matching set. Specifying aflag
ofend
and anoffset
of -8 will return records starting from the ninth last record in the matching set.To retrieve the next record after the last returned by the previous
fetch
, you would pass aflag
ofcurrent
and anoffset
of 1.count
The
count
argument specifies the maximum number of records to be retrieved.Passing a
count
value of 0 is valid. This causesfetch
to change the current record without actually retrieving any data.Using a negative value for
count
is also valid. This causesfetch
to return all the records in the matching set from the starting position (specified byflag
andoffset
).columns
The
columns
argument is used to specify which columns should be included in the returned records. The argument can be either aString
, aString[]
or aArrayList<String>
. In its simplest form eachString
contains a single column name, or several column names separated by semi-colons or commas.The value of the
columns
argument can be more than simple column names. See the section on Specifying columns for details.
There are a number of variations of the fetch
method. See the reference documentation for details of each one.
For example:
- Retrieve the first record from the start of a set of matching records:
Module parties = new Module("eparties", session); String columns = "NamFirst;NamLast"; parties.fetch("start", 0, 1, columns);
The columns argument can also be specified as a
String[]
:Module parties = new Module("eparties", session); String[] columns = { "NamFirst", "NamLast" }; parties.fetch("start", 0, 1, columns);
- Return all of the results in a matching set:
Module parties = new Module("eparties", session); String[] columns = { "NamFirst", "NamLast" }; ModuleFetchResult result = parties.fetch("start", 0, -1, columns);
- Change the current record to the next record in the set of matching records
without retrieving any data:
parties.fetch("current", 1, 0);
- Retrieve the last record from the end of a set of matching records:
Module parties = new Module("eparties", session); String[] columns = { "NamFirst", "NamLast" }; ModuleFetchResult result = parties.fetch("end", 0, 1, columns);
The fetch
method returns records requested in a ModuleFetchResult
object. It contains three read-only properties:
count
An
int
(accessed using thegetCount
method) specifying the number of records returned by thefetch
request.hits
A
long
(accessed using thegetHits
method) specifying the estimated number of matches in the result set. This number is returned for eachfetch
because the estimate can decrease as records in the result set are processed by thefetch
method.rows
A
Map[]
containing the set of records requested. EachMap
contains entries for each column requested.
Note: The IMu Map class is a subclass of Java’s
standard HashMap
. It defines its key type to be String
. It
also provides some convenience methods for converting the types of
elements stored in the map.
For example, retrieve the count
and hits
properties and iterate over all
of the returned records using the rows
property:
String[] columns = { "NamFirst", "NamLast" }; ModuleFetchResult result = parties.fetch("start", 0, 2, columns); int count = result.getCount(); long hits = result.getHits(); Map[] rows = result.getRows(); System.out.format("Count: %d%n", count); System.out.format("Hits: %d%n", hits); System.out.println("Rows:"); for (int i = 0; i < rows.length; i++) { Map row = rows[i]; int rowNum = row.getInt("rownum"); long irn = row.getLong("irn"); String firstName = row.getString("NamFirst"); String lastName = row.getString("NamLast"); System.out.format(" %d. %s, %s (%d)%n", rowNum, lastName, firstName, irn); }
This will produce output similar to the following:
Count: 2 Hits: 4 Rows: 1. ECCLES-SMITH, Kate (100573) 2. SMITH, Ian (100301)
Specifying columns
This section specifies the values that can be included or used as the
columns
arguments to the Module
class fetch
method.
These are simple column names of the type already mentioned, for example:
NamFirst
The values of atomic columns are returned as a String
:
String[] columns = { "NamFirst" }; ModuleFetchResult result = parties.fetch("start", 0, 1, columns); Map[] rows = result.getRows(); for (int i = 0; i < rows.length; i++) { Map row = rows[i]; String first = row.getString("NamFirst"); // ⋯ }
Nested tables are columns that contain a list of values. They are specified similarly to atomic columns:
NamRoles_tab
The values of nested tables are returned as a String[]
. Each array member
is a String
that corresponds to a row from the nested table:
String[] columns = { "NamRoles_tab" }; ModuleFetchResult result = parties.fetch("start", 0, 1, columns); Map[] rows = result.getRows(); for (int i = 0; i < rows.length; i++) { Map row = rows[i]; String[] roles = row.getStrings("NamRoles_tab"); for (int j = 0; j < roles.length; j++) { String role = roles[j]; // ⋯ } }
An attachment is a link between a record in a module and a record in the same or another module. The columns from an attached record can be specified by first specifying the attachment column and then the column to retrieve from the attached record:
SynSynonymyRef_tab.SummaryData
Multiple columns can be specified from the attached record:
SynSynonymyRef_tab.(NamFirst,NamLast)
The return values of columns from attached records depends on the type of the
attachment column. If the attachment column is atomic then the column values
are returned as a Map
. If the attachment column is a nested table the
values are returned as a Map[]
. Each Map
contains the requested column
values for each attached record:
String[] columns = { "SynSynonymyRef_tab.(NamFirst,NamLast)" }; ModuleFetchResult result = parties.fetch("start", 0, 1, columns); Map[] rows = result.getRows();for (int i = 0; i < rows.length; i++) { Map row = rows[i]; Map[] synonymies = row.getMaps("SynSynonymyRef_tab"); for (int j = 0; j < synonymies.length; j++) { Map synonymy = synonymies[j]; String first = synonymy.getString("NamFirst"); String last = synonymy.getString("NamLast"); // ⋯ } }
A reverse attachment allows you to specify columns from other records in the same module or other modules that have the current record attached to a specified column.
For example:
- Retrieve the TitMainTitle (Main Title) column for all Catalogue records
that have the current Parties record attached to their CreCreatorRef_tab
(Creator) column:
<ecatalogue:CreCreatorRef_tab>.TitMainTitle
- Retrieve the NarTitle (Title) column for all Narratives records that have
the current Narrative record attached to their HieChildNarrativesRef_tab
(Child Narratives) column:
<enarratives:HieChildNarrativesRef_tab>.NarTitle
Multiple columns can be specified from the reverse attachment record:
<ecatalogue:CreCreatorRef_tab>.(TitMainTitle,TitObjectCategory)
Reverse attachments are returned as an Map[]
. Each Map
contains the
requested column values from each record from the specified module (The
Catalogue module in the example below) that has the current record attached to
the specified column (The CreCreatorRef_tab column in the example below):
String[] columns = { "<ecatalogue:CreCreatorRef_tab>.(TitMainTitle,TitObjectCategory)" }; ModuleFetchResult result = parties.fetch("start", 0, 1, columns); Map[] rows = result.getRows(); for (int i = 0; i < rows.length; i++) { Map row = rows[i]; Map[] objects = row.getMaps("ecatalogue:CreCreatorRef_tab"); for (int j = 0; j < objects.length; j++) { Map object = objects[j]; String title = object.getString("TitMainTitle"); String category = object.getString("TitObjectCategory"); // ⋯ } }
A set of nested table columns can be grouped by specifying them between square brackets.
For example, to group the Contributors and their Role from the Narratives module:
[NarContributorRef_tab.SummaryData,NarContributorRole_tab]
Each corresponding rows of the supplied nested tables are returned as a single table row in the returned results. By default, the group is given a name of group1, group2 and so on. This group name can be changed by prefixing the grouped columns with an alternative name:
contributors=[NarContributorRef_tab.SummaryData,NarContributorRole_tab]
The grouped nested tables are returned as a Map[]
. Each Map
contains
the requested column values for corresponding rows from the nested tables:
String[] columns = { "[NarContributorRef_tab.SummaryData,NarContributorRole_tab]" }; ModuleFetchResult result = narratives.fetch("start", 0, 1, columns); Map[] rows = result.getRows();for (int i = 0; i < rows.length; i++) { Map row = rows[i]; Map[] groupedRows = row.getMaps("group1"); for (int j = 0; j < groupedRows.length; j++) { Map groupedRow = groupedRows[j]; // NarContributorRef_tab is an attachment column. Map contributor = groupedRow.getMap("NarContributorRef_tab"); String name = contributor.getString("SummaryData"); String role = groupedRow.getString("NarContributorRole_tab"); // ⋯ } }
Virtual columns are columns that do not actually exist in the EMu table being accessed. Instead, the IMu server interprets the request for the column and builds an appropriate response. Certain virtual columns can only be used in certain modules as follows:
The following virtual columns can be used in any EMu module:
-
insertedTimeStamp
Returns the insertion date and time of the record using the format
YYYY-MM-DDThh:mm:ss
, for example1999-12-31T23:59:59
. This is similar to the ISO8601 date format except the time zone designator is not included. -
modifiedTimeStamp
Returns the modification date and time of the record using the format
YYYY-MM-DDThh:mm:ss
.
String[] columns = { "insertedTimeStamp", "modifiedTimeStamp" }; ModuleFetchResult result = parties.fetch("start", 0, 1, columns); Map[] rows = result.getRows(); for (int i = 0; i < rows.length; i++) { Map row = rows[i]; String inserted = row.getString("insertedTimeStamp"); String modified = row.getString("modifiedTimeStamp"); // ⋯ }
The following virtual columns can be used in any EMu module except Multimedia:
- application
Returns information about the preferred application multimedia attached to a record.
Note: Currently the preferred multimedia is the same as the first entry in the list returned by the applications virtual column. However, future versions of EMu may allow other multimedia to be flagged as preferred, in which case the application column will return information for the preferred multimedia, rather than the first one.
- applications
Returns information about all of the application multimedia attached to a record.
-
audio
Returns information about the preferred audio multimedia attached to a record.
- audios
Returns information about all of the audio multimedia attached to a record.
- image
Returns information about the preferred image multimedia attached to a record.
- images
Returns information about all of the image multimedia attached to a record.
- multimedia
Returns information about all of the multimedia attached to a record.
- video
Returns information about the preferred video multimedia attached to a record.
- videos
Returns information about all of the video multimedia attached to a record.
See Multimedia for more information.
The following virtual columns can only be used in the Multimedia module:
- master
Returns information about the master multimedia file.
- resolutions
Returns information about all multimedia resolutions.
- resource
Returns minimal information about the master multimedia file including an open file handle to a temporary copy of the multimedia file.
- resources
The same as the resource virtual column except that information and file handles are supplied for all multimedia files.
- supplementary
Returns information about all supplementary multimedia files.
- thumbnail
Returns information about the multimedia thumbnail.
See Multimedia for more information.
The following virtual column can only be used in the Narratives module:
- trails
Returns information about the position of the current Narratives record in the Narratives hierarchy.
The following virtual column can only be used in the Collection Descriptions module:
- extUrlFull_tab
A fetch set allows you to pre-register a group of columns by a single name.
That name can then be passed to the fetch
method to retrieve the specified
columns.
Fetch sets are useful if the fetch
method will be called several times with
the same set of columns because:
- The required columns do no have to be specified every time the
fetch
method is called. This is useful when maintaining state. - Every time the
fetch
method is called the IMu server must parse the supplied columns and check them against the EMu schema. For complex column sets, particularly those involving several references or reverse references, this can take time.
The Module
class addFetchSet
method is used to register a set of
columns. This method takes two arguments:
name
The name to use for the column set. The value of this argument can be passed to any call to the
fetch
method and the set of columns specified by thecolumns
argument will be returned.columns
The set of columns to be associated with the
name
argument.
The Module
class addFetchSets
method is similar except that
multiple sets can be registered at one time.
The results are returned as if you had supplied the columns directly to the
fetch
method.
For example:
- Add a single fetch set using the
addFetchSet
method:String[] columns = { "NamFirst", "NamLast", "NamRoles_tab" }; parties.addFetchSet("person_details", columns);
- Add multiple fetch sets using the
addFetchSets
method:Map sets = new Map(); sets.put("person_details", "NamFirst;NamLast;NamRoles_tab"); sets.put("organisation_details", "NamOrganisation;NamOrganisationAcronym"); parties.addFetchSets(sets);
- Retrieve a fetch set using the
fetch
method:ModuleFetchResult result = parties.fetch("start", 0, 1, "person_details"); Map[] rows = result.getRows();for (int i = 0; i < rows.length; i++) { Map row = rows[i]; String first = row.getString("NamFirst"); String last = row.getString("NamLast"); String[] roles = row.getStrings("NamRoles_tab"); for (int j = 0; j < roles.length; j++) { String role = roles[j]; // ⋯ } }
Warning
The fetch set name must be the only value passed as the
Fetch
methodcolumns
argument. This may be revised in a future version of the IMu API.
Columns can be renamed in the returned results by prefixing them with an alternative name:
first_name=NamFirst
The value of the specified column is now returned using the alternative name:
String[] columns = { "first_name=NamFirst" }; ModuleFetchResult result = parties.fetch("start", 0, 1, columns); Map[] rows = result.getRows();for (int i = 0; i < rows.length; i++) { Map row = rows[i]; String first = row.getString("first_name"); // ⋯ }
Alternative names can be supplied to other column specifications as well:
roles=NamRoles_tab
synonyms=SynSynonymyRef_tab.(NamFirst,NamLast)
objects=<ecatalogue:CreCreatorRef_tab>.(TitMainTitle,TitObjectCategory)
Alternative names can also be used for any columns specified between round brackets or square brackets:
SynSynonymyRef_tab.(first_name=NamFirst,last_name=NamLast)
contributors=[contributor=NarContributorRef_tab.SummaryData,role=NarContributorRole_tab]
Alternative names can also be supplied in fetch sets:
String[] columns = { "first_name=NamFirst", "last_name=NamLast", "roles=NamRoles_tab" }; parties.addFetchSet("person_details", columns);
A Simple example
In this example we build a simple JSP web page to search the Parties module by last name and display the full set of results.
First build the search page, which is a plain HTML form:
<head> <title>Party Search</title> </head> <body> <form action="a-simple-example.jsp"> <p>Enter a last name to search for (e.g. Smith):</p> <input type="text" name="name"/> <input type="submit" value="Search"/> </form> </body>
Next build the results page (source code), which runs the search and displays the results:
<%@ page import="com.kesoftware.imu.*" %> <% String name = request.getParameter("name"); if (name == null || name.isEmpty()) throw new Exception("missing 'name' parameter"); Terms terms = new Terms(); terms.add("NamLast", name); Session imuSession = new Session("imu.mel.kesoftware.com", 40136); Module module = new Module("eparties", imuSession); module.findTerms(terms); String[] columns = { "NamFirst", "NamLast" }; ModuleFetchResult results = module.fetch("start", 0, -1, columns); long hits = results.getHits(); Map[] rows = results.getRows();%><!DOCTYPE html> <html> <head> <title>IMu Java API - A Simple Example</title> </head> <body> <p>Number of matches: <% out.print(hits); %></p> <table><%for (int i = 0; i < rows.length; i++) { Map row = rows[i]; long rowNum = row.getLong("rownum"); String first = row.getString("NamFirst"); String last = row.getString("NamLast"); %> <tr> <td><% out.print(rowNum); %></td> <td><% out.print(first); out.print(" "); out.print(last); %></td> </tr> <% }%> </table> </body> </html>
In this example the name
parameter entered via the HTML search page is
submitted to the JSP script. The script searches for parties records that have
the entered value as a last name and display the parties first and last names
in an HTML table.
Note: To deploy and run JSP, a compatible web server with a servlet
container, such as Apache Tomcat or Jetty, is required. The
request
object used to retrieve the name parameter is supplied
by the servlet container.