Data-Seek
view release on metacpan or search on metacpan
README.mkdn view on Meta::CPAN
# NAME
Data::Seek - Search Complex Data Structures
# VERSION
version 0.09
# SYNOPSIS
use Data::Seek;
my $hash = {...};
my $seeker = Data::Seek->new(data => $hash);
my $result = $seeker->search(...);
my $data = $result->data;
# DESCRIPTION
Data::Seek is used for querying complex data structures. This module allows you
to select and return specific node(s) in a hierarchical data structure using a
simple and intuitive query syntax. The results can be returned as a list of
values, or as a hash object in the same shape as the original.
# ENCODING
During the processing of flattening a data structure with nested data, the
following data structure would be converted into a collection of endpoint/value
pairs.
{
'id' => 12345,
'patient' => {
'name' => {
'first' => 'Bob',
'last' => 'Bee'
}
},
'medications' => [{
'aceInhibitors' => [{
'name' => 'lisinopril',
'strength' => '10 mg Tab',
'dose' => '1 tab',
'route' => 'PO',
'sig' => 'daily',
'pillCount' => '#90',
'refills' => 'Refill 3'
}],
'antianginal' => [{
'name' => 'nitroglycerin',
'strength' => '0.4 mg Sublingual Tab',
'dose' => '1 tab',
'route' => 'SL',
'sig' => 'q15min PRN',
'pillCount' => '#30',
'refills' => 'Refill 1'
}],
}]
}
Given the aforementioned data structure, the following would be the resulting
flattened structure comprised of endpoint/value pairs.
{
'id' => 12345,
'medications:0.aceInhibitors:0.dose' => '1 tab',
'medications:0.aceInhibitors:0.name' => 'lisinopril',
'medications:0.aceInhibitors:0.pillCount' => '#90',
'medications:0.aceInhibitors:0.refills' => 'Refill 3',
'medications:0.aceInhibitors:0.route' => 'PO',
'medications:0.aceInhibitors:0.sig' => 'daily',
'medications:0.aceInhibitors:0.strength' => '10 mg Tab',
'medications:0.antianginal:0.dose' => '1 tab',
'medications:0.antianginal:0.name' => 'nitroglycerin',
'medications:0.antianginal:0.pillCount' => '#30',
'medications:0.antianginal:0.refills' => 'Refill 1',
'medications:0.antianginal:0.route' => 'SL',
'medications:0.antianginal:0.sig' => 'q15min PRN',
'medications:0.antianginal:0.strength' => '0.4 mg Sublingual Tab',
'patient.name.first' => 'Bob'
'patient.name.last' => 'Bee',
}
This structure provides the endpoint strings which will be matched against using
the querying strategy.
# QUERYING
During the processing of querying the data structure, the criteria (query
expressions) are converted into a series of regular expressions to be applied
sequentially, filtering/reducing the endpoints and producing a data set of
matching nodes or throwing an exception explaining the search failure.
- **Node Expression**
my $result = $seeker->search(...);
# given "id"
{ id => 12345 }
The node expression is a part of a criterion, which preforms an exact match
against a node in the data structure. It is a string which can contain letters,
numbers, and/or underscores.
- **Step Expression**
my $result = $seeker->search(...);
# given "patient.name.first"
{ patient => { name => { first => "Bob" } } }
# given "patient.name.last"
{ patient => { name => { last => "Bee" } } }
The step expression is a criterion, or part of a criterion, made up of one or
more node expressions separated using the period character, which matches
against nodes in the data structure. It is a string which can contain letters,
numbers, and/or underscores, separated using periods.
- **Index Expression**
my $result = $seeker->search(...);
# given "medications:0.aceInhibitors:0.dose"
{ medications => [{ aceInhibitors => [{ dose => "1 tab" }] }] }
# given "medications:0.aceInhibitors:0.name"
{ medications => [{ aceInhibitors => [{ name => "lisinopril" }] }], }
# given "medications:0.aceInhibitors:0.pillCount"
{ medications => [{ aceInhibitors => [{ pillCount => "#90" }] }] }
The index expression is a criterion, or part of a criterion, having a node
expressions suffixed with a colon followed by a number denoting that it should
only match an array which has an index corresponding to the numeric portion of
the suffix. It is a string which can contain letters, numbers, and/or
underscores, suffixed with a semi-colon followed by a number.
- **Iterator Expression**
my $result = $seeker->search(...);
# given "@medications.@aceInhibitors.dose"
{ medications => [{ aceInhibitors => [{ dose => "1 tab" }] }] }
# given "@medications.@aceInhibitors.name"
{ medications => [{ aceInhibitors => [{ name => "lisinopril" }] }], }
# given "@medications.@aceInhibitors.pillCount"
{ medications => [{ aceInhibitors => [{ pillCount => "#90" }] }] }
README.mkdn view on Meta::CPAN
my $result = $seeker->search(...);
# given "**.first"
{ patient => { name => { first => "Bob" } } }
# given "**.last"
{ patient => { name => { last => "Bee" } } }
# given "patient.**"
{ patient => { name => { first => "Bob", last => "Bee" } } }
# given "medications**.pillCount"
{
medications => [{
aceInhibitors => [{ pillCount => "#90" }],
antianginal => [{ pillCount => "#30" }],
}],
}
The greedy-wildcard expression is a criterion, or part of a criterion, which
matches against any multitude of nodes having a double "star" character match
and represent one or more of any character. It is a string which can contain
letters, numbers, underscores, and/or a double star character.
# ATTRIBUTES
## data
$seeker->data;
$seeker->data({...});
The data structure to be introspected, must be a hash reference, which is
coerced into a [Data::Object::Hash](https://metacpan.org/pod/Data::Object::Hash) object.
## ignore
$seeker->ignore;
$seeker->ignore(1);
Bypass exceptions thrown when a criterion is invalid or no data matches can be
found. This attribute must be an integer, which is coerced into a
[Data::Object::Integer](https://metacpan.org/pod/Data::Object::Integer) object.
# METHODS
## search
my $search = $seeker->search('id', 'person.name.*');
Prepare a search object to use the supplied criteria and return a search
object. Introspection is triggered when the result method is enacted. See
[Data::Seek::Search](https://metacpan.org/pod/Data::Seek::Search) for usage information.
# CONCEPT
The follow is a short and simple overview of the strategy and syntax used by
Data::Seek to query complex data structures. The overall idea behind Data::Seek
is to flatten/fold the data structure, reduce it by applying a series patterns,
then, unflatten/unfold and operate on the new data structure. The introspection
strategy is to flatten the data structure producing a non-hierarchical data
structure where its keys represent endpoints (using dot-notation and colons to
separate (and denote) nested hash keys and array indices respectively) within
the structure.
# AUTHOR
Al Newkirk <anewkirk@ana.io>
# COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by Al Newkirk.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
( run in 1.368 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )