1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.appointment.modules.solrsearchapp.service;
35
36 import java.time.LocalDateTime;
37 import java.time.format.DateTimeParseException;
38 import java.util.AbstractMap.SimpleImmutableEntry;
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.List;
42 import java.util.Map;
43
44 import javax.servlet.http.HttpServletRequest;
45
46 import org.apache.commons.lang3.StringUtils;
47 import org.apache.commons.lang3.ArrayUtils;
48 import org.apache.solr.client.solrj.SolrQuery;
49 import org.apache.solr.client.solrj.util.ClientUtils;
50
51 public class SolrQueryService
52 {
53 private static final String SOLR_FIELD_SITE = "site";
54 private static final String SOLR_FIELD_CATEGORY = "categorie";
55 public static final String SOLR_FIELD_FORM_UID_TITLE = "form_id_title_string";
56 private static final String SOLR_FIELD_FORM_UID = "uid_form_string";
57 private static final String SOLR_QUERY_ALL = "*:*";
58 private static final String SOLR_FILTERQUERY_ALLOWED_NOW = "{!frange l=0}sub(sub(ms(date),mul(3600000,min_hours_before_appointment_long)),ms())";
59 private static final String SOLR_FILTERQUERY_DAY_OPEN = "day_open_string:true";
60 private static final String SOLR_FILTERQUERY_ENABLED = "enabled_string:true";
61 private static final String SOLR_FILTERQUERY_ACTIVE = "appointment_active_string:true";
62 private static final String SOLR_FIELD_TYPE = "type";
63 public static final String SOLR_FIELD_DATE = "date";
64 private static final String SOLR_FIELD_MINUTE_OF_DAY = "minute_of_day_long";
65 private static final String SOLR_NB_CONSECUTIVES_SLOTS = "nb_consecutives_slots_long";
66 private static final String SOLR_MAX_CONSECUTIVES_SLOTS = "max_consecutives_slots_long";
67 private static final String SOLR_ROLE = "role";
68 public static final String SOLR_FIELD_DAY_OF_WEEK = "day_of_week_long";
69 private static final String SOLR_TYPE_APPOINTMENT_SLOT = "appointment-slot";
70 public static final String VALUE_FQ_EMPTY = "__EMPTY__";
71
72 public static final List<SimpleImmutableEntry<String, String>> EXACT_FACET_QUERIES = Collections
73 .unmodifiableList( Arrays.asList( new SimpleImmutableEntry<>( SOLR_FIELD_SITE, Utilities.PARAMETER_SITE ),
74 new SimpleImmutableEntry<>( SOLR_FIELD_CATEGORY, Utilities.PARAMETER_CATEGORY ),
75 new SimpleImmutableEntry<>( SOLR_FIELD_FORM_UID, Utilities.PARAMETER_FORM ) ) );
76
77 public static final List<SimpleImmutableEntry<String, String>> FACET_FIELDS = Collections
78 .unmodifiableList( Arrays.asList( new SimpleImmutableEntry<>( SOLR_FIELD_SITE, Utilities.MARK_ITEM_SITES ),
79 new SimpleImmutableEntry<>( SOLR_FIELD_CATEGORY, Utilities.MARK_ITEM_CATEGORIES ),
80 new SimpleImmutableEntry<>( SOLR_FIELD_FORM_UID_TITLE, Utilities.MARK_ITEM_FORMS ) ) );
81
82 private SolrQueryService( )
83 {
84
85 }
86
87 public static SolrQuery getCommonFilteredQuery( HttpServletRequest request, Map<String, String> searchParameters,
88 Map<String, String [ ]> searchMultiParameters )
89 {
90 SolrQuery query = new SolrQuery( );
91 query.setQuery( SOLR_QUERY_ALL );
92 query.addFilterQuery( SOLR_FIELD_TYPE + ":" + SOLR_TYPE_APPOINTMENT_SLOT );
93 query.addFilterQuery( SOLR_FILTERQUERY_ALLOWED_NOW );
94 query.addFilterQuery( SOLR_FILTERQUERY_DAY_OPEN );
95 query.addFilterQuery( SOLR_FILTERQUERY_ENABLED );
96 query.addFilterQuery( SOLR_FILTERQUERY_ACTIVE );
97
98 for ( SimpleImmutableEntry<String, String> entry : EXACT_FACET_QUERIES )
99 {
100 addFacetToQuery( query, request, searchParameters, entry );
101 }
102
103 StringBuilder sbFqDaysOfWeek = new StringBuilder( );
104 String [ ] searchDays = Utilities.getSearchMultiParameter( Utilities.PARAMETER_DAYS_OF_WEEK, request, searchMultiParameters );
105 if ( ArrayUtils.isNotEmpty( searchDays ) )
106 {
107 sbFqDaysOfWeek.append( "{!tag=tag" + SOLR_FIELD_DAY_OF_WEEK + "}" + SOLR_FIELD_DAY_OF_WEEK + ":(" );
108 for ( int nDay = 0; nDay < searchDays.length; nDay++ )
109 {
110 if ( nDay > 0 )
111 {
112 sbFqDaysOfWeek.append( " OR " );
113 }
114 sbFqDaysOfWeek.append( searchDays [nDay] );
115 }
116 sbFqDaysOfWeek.append( ")" );
117 }
118 query.addFilterQuery( sbFqDaysOfWeek.toString( ) );
119 query.addFacetField( "{!ex=tag" + SOLR_FIELD_DAY_OF_WEEK + "}" + SOLR_FIELD_DAY_OF_WEEK );
120
121 String strFromDate = Utilities.getSearchParameterValue( Utilities.PARAMETER_FROM_DATE, request, searchParameters );
122 String strFromTime = Utilities.getSearchParameterValue( Utilities.PARAMETER_FROM_TIME, request, searchParameters );
123 String strToDate = Utilities.getSearchParameterValue( Utilities.PARAMETER_TO_DATE, request, searchParameters );
124 String strToTime = Utilities.getSearchParameterValue( Utilities.PARAMETER_TO_TIME, request, searchParameters );
125 LocalDateTime localDateTimeFrom = null;
126 try
127 {
128 localDateTimeFrom = LocalDateTime.parse( strFromDate + " " + strFromTime, Utilities.inputFormatter );
129 }
130 catch( DateTimeParseException e )
131 {
132 localDateTimeFrom = null;
133 }
134 String strSolrDateTimeFrom = "*";
135 if ( localDateTimeFrom != null )
136 {
137 strSolrDateTimeFrom = localDateTimeFrom.format( Utilities.outputFormatter );
138 }
139 LocalDateTime localDateTimeTo = null;
140 try
141 {
142 localDateTimeTo = LocalDateTime.parse( strToDate + " " + strToTime, Utilities.inputFormatter );
143 }
144 catch( DateTimeParseException e )
145 {
146 localDateTimeTo = null;
147 }
148 String strSolrDateTimeTo = "*";
149 if ( localDateTimeTo != null )
150 {
151 strSolrDateTimeTo = localDateTimeTo.format( Utilities.outputFormatter );
152 }
153 query.addFilterQuery( SOLR_FIELD_DATE + ":[" + strSolrDateTimeFrom + " TO " + strSolrDateTimeTo + "]" );
154 String strFromDayMinute = Utilities.getSearchParameterValue( Utilities.PARAMETER_FROM_DAY_MINUTE, request, searchParameters );
155 String strToDayMinute = Utilities.getSearchParameterValue( Utilities.PARAMETER_TO_DAY_MINUTE, request, searchParameters );
156 String strSolrDayMinuteFrom = "*";
157 if ( strFromDayMinute != null )
158 {
159 strSolrDayMinuteFrom = strFromDayMinute;
160 }
161 String strSolrDayMinuteTo = "*";
162 if ( strToDayMinute != null )
163 {
164 strSolrDayMinuteTo = strToDayMinute;
165 }
166 query.addFilterQuery( SOLR_FIELD_MINUTE_OF_DAY + ":[" + strSolrDayMinuteFrom + " TO " + strSolrDayMinuteTo + "]" );
167
168 String strNbConsecutiveSlots = Utilities.getSearchParameterValue( Utilities.PARAMETER_NB_SLOTS, request, searchParameters );
169 int nbConsecutiveSlots = Integer.parseInt( strNbConsecutiveSlots );
170 query.addFilterQuery( SOLR_NB_CONSECUTIVES_SLOTS + ":[" + nbConsecutiveSlots + " TO *]" );
171 query.addFilterQuery( SOLR_MAX_CONSECUTIVES_SLOTS + ":[" + nbConsecutiveSlots + " TO *]" );
172
173 String strRole = Utilities.getSearchParameterValue( Utilities.PARAMETER_ROLE, request, searchParameters );
174 if ( StringUtils.isNotEmpty( strRole ) && !"none".equals( strRole ) )
175 {
176 query.addFilterQuery( SOLR_ROLE + ":" + strRole );
177 }
178 return query;
179 }
180
181 private static void addFacetToQuery( SolrQuery query, HttpServletRequest request, Map<String, String> searchParameters,
182 SimpleImmutableEntry<String, String> entry )
183 {
184 String strValue = Utilities.getSearchParameterValue( entry.getValue( ), request, searchParameters );
185 String strFacetField;
186 if ( SOLR_FIELD_FORM_UID.equals( entry.getKey( ) ) )
187 {
188 strFacetField = SOLR_FIELD_FORM_UID_TITLE;
189 }
190 else
191 {
192 strFacetField = entry.getKey( );
193 }
194 if ( StringUtils.isNotBlank( strValue ) )
195 {
196 String strFilterQuery;
197 if ( VALUE_FQ_EMPTY.equals( strValue ) )
198 {
199 strFilterQuery = entry.getKey( ) + ":" + "\"\" OR (*:* NOT " + entry.getKey( ) + ":*)";
200 }
201 else
202 {
203 strFilterQuery = entry.getKey( ) + ":" + ClientUtils.escapeQueryChars( strValue );
204 }
205 query.addFilterQuery( "{!tag=tag" + strFacetField + "}" + strFilterQuery );
206 strFacetField = "{!ex=tag" + strFacetField + "}" + strFacetField;
207 }
208 query.addFacetField( strFacetField );
209 }
210 }