source: trunk/src/groovy/dbnp/query/StudySearch.groovy @ 1415

Last change on this file since 1415 was 1415, checked in by robert@…, 10 years ago

First version of advanced querying

File size: 6.0 KB
Line 
1/**
2 * StudySearch Domain Class
3 *
4 * This class provides querying capabilities for searching for studies
5 *
6 * @author  Robert Horlings (robert@isdat.nl)
7 * @since       20110118
8 * @package     dbnp.query
9 *
10 * Revision information:
11 * $Rev$
12 * $Author$
13 * $Date$
14 */
15package dbnp.query
16
17import dbnp.studycapturing.*;
18
19class StudySearch extends Search {
20        public StudySearch() {
21                this.entity = "Study";
22                this.view = "studyresults";
23        }
24
25        /**
26         * Searches for studies based on the given criteria. All criteria have to be satisfied and
27         * criteria for the different entities are satisfied as follows:
28         *
29         *              Study.title = 'abc'             
30         *                              All returned studies will have title 'abc'
31         *             
32         *              Subject.species = 'human'
33         *                              All returned studies will have one or more subjects with species = 'human' 
34         *
35         *              Sample.name = 'sample 1'
36         *                              All returned studies will have one or more samples with name = 'sample 1'
37         *
38         *              Event.startTime = '0s'
39         *                              All returned studies will have one or more events with start time = '0s' 
40         *
41         *              Assay.module = 'metagenomics'
42         *                              All returned studies will have one or more assays with module = 'metagenomics' 
43         *
44         * When searching the system doesn't look at the connections between different entities. This means,
45         * the system doesn't look for human subjects having a sample with name 'sample 1'. The sample 1 might
46         * as well belong to a mouse subject and still the study satisfies the criteria.
47         *
48         * When searching for more than one criterium per entity, these are taken combined. Searching for
49         *
50         *              Subject.species = 'human'
51         *              Subject.name = 'Jan'
52         *
53         *  will result in all studies having a human subject named 'Jan'. Studies with only a mouse subject
54         *  named 'Jan' or a human subject named 'Kees' won't satisty the criteria.
55         *     
56         */
57        @Override
58        void execute() {
59                // TODO: check for authorization for these studies?
60                def studies = Study.list();
61
62                // If no criteria are found, return all studies
63                if( !criteria || criteria.size() == 0 ) {
64                        results = studies;
65                        return;
66                }
67
68                // Perform filters
69                studies = filterOnStudyCriteria( studies );
70                studies = filterOnSubjectCriteria( studies );
71                studies = filterOnSampleCriteria( studies );
72                studies = filterOnEventCriteria( studies );
73                studies = filterOnAssayCriteria( studies );
74
75                // Save matches
76                results = studies;
77        }
78
79        /**
80         * Filters the given list of studies on the study criteria
81         * @param studies       Original list of studies
82         * @return                      List with all studies that match the Study-criteria
83         */
84        protected List filterOnStudyCriteria( List studies ) {
85                return filterEntityList( studies, getEntityCriteria( 'Study' ), { study, criterium ->
86                        try {
87                                return this.compare( study.getFieldValue( criterium.field ), criterium );
88                        } catch( Exception e ) {
89                                // An exception occurs if the given field doesn't exist. In that case, this criterium will fail.
90                                // TODO: Maybe give the user a choice whether he want's to include these studies or not
91                                return false;
92                        }
93                });
94        }
95
96        /**
97         * Filters the given list of studies on the subject criteria
98         * @param studies       Original list of studies
99         * @return                      List with all studies that match the Subject-criteria
100         */
101        protected List filterOnSubjectCriteria( List studies ) {
102                return filterEntityList( studies, getEntityCriteria( 'Subject' ), { study, criterium ->
103                        if( !study.subjects?.size() )
104                                return false
105
106                        for( subject in study.subjects ) {
107                                try {
108                                        if( this.compare( subject.getFieldValue( criterium.field ), criterium ) ) {
109                                                return true
110                                        }
111                                } catch( Exception e ) {
112                                        // An exception occurs if the given field doesn't exist. In that case, this criterium will fail.
113                                        // TODO: Maybe give the user a choice whether he want's to include these studies or not
114                                }
115                        }
116                       
117                        return false;
118                });
119        }
120
121        /**
122         * Filters the given list of studies on the sample criteria
123         * @param studies       Original list of studies
124         * @return                      List with all studies that match the sample-criteria
125         */
126        protected List filterOnSampleCriteria( List studies ) {
127                return filterEntityList( studies, getEntityCriteria( 'Sample' ), { study, criterium ->
128                        if( !study.samples?.size() )
129                                return false
130
131                        for( sample in study.samples ) {
132                                try {
133                                        if( this.compare( sample.getFieldValue( criterium.field ), criterium ) )
134                                                return true
135                                } catch( Exception e ) {
136                                        // An exception occurs if the given field doesn't exist. In that case, this criterium will fail.
137                                        // TODO: Maybe give the user a choice whether he want's to include these studies or not
138                                }
139                        }
140                        return false;
141                       
142                });
143        }
144
145        /**
146         * Filters the given list of studies on the event criteria
147         * @param studies       Original list of studies
148         * @return                      List with all studies that match the event-criteria
149         */
150        protected List filterOnEventCriteria( List studies ) {
151                return filterEntityList( studies, getEntityCriteria( 'Event' ), { study, criterium ->
152                        if( !study.events?.size() )
153                                return false
154
155                        for( event in study.events ) {
156                                try {
157                                        if( this.compare( event.getFieldValue( criterium.field ), criterium ) )
158                                                return true
159                                } catch( Exception e ) {
160                                        // An exception occurs if the given field doesn't exist. In that case, this criterium will fail.
161                                        // TODO: Maybe give the user a choice whether he want's to include these studies or not
162                                }
163                        }
164                        return false;
165                });
166        }
167       
168       
169        /**
170         * Filters the given list of studies on the assay criteria
171         * @param studies       Original list of studies
172         * @return                      List with all studies that match the assay-criteria
173         */
174        protected List filterOnAssayCriteria( List studies ) {
175                return filterEntityList( studies, getEntityCriteria( 'Assay' ), { study, criterium ->
176                        if( !study.assays?.size() )
177                                return false
178
179                        for( assay in study.assays ) {
180                                try {
181                                        if( this.compare( assay.getFieldValue( criterium.field ), criterium ) )
182                                                return true
183                                } catch( Exception e ) {
184                                        // An exception occurs if the given field doesn't exist. In that case, this criterium will fail.
185                                        // TODO: Maybe give the user a choice whether he want's to include these studies or not
186                                }
187                        }
188                        return false;
189                });
190        }
191}
Note: See TracBrowser for help on using the repository browser.