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_ROLE = "role";
67 public static final String SOLR_FIELD_DAY_OF_WEEK = "day_of_week_long";
68 private static final String SOLR_TYPE_APPOINTMENT_SLOT = "appointment-slot";
69 public static final String VALUE_FQ_EMPTY = "__EMPTY__";
70
71 public static final List<SimpleImmutableEntry<String, String>> EXACT_FACET_QUERIES = Collections
72 .unmodifiableList( Arrays.asList( new SimpleImmutableEntry<>( SOLR_FIELD_SITE, Utilities.PARAMETER_SITE ),
73 new SimpleImmutableEntry<>( SOLR_FIELD_CATEGORY, Utilities.PARAMETER_CATEGORY ),
74 new SimpleImmutableEntry<>( SOLR_FIELD_FORM_UID, Utilities.PARAMETER_FORM ) ) );
75
76 public static final List<SimpleImmutableEntry<String, String>> FACET_FIELDS = Collections
77 .unmodifiableList( Arrays.asList( new SimpleImmutableEntry<>( SOLR_FIELD_SITE, Utilities.MARK_ITEM_SITES ),
78 new SimpleImmutableEntry<>( SOLR_FIELD_CATEGORY, Utilities.MARK_ITEM_CATEGORIES ),
79 new SimpleImmutableEntry<>( SOLR_FIELD_FORM_UID_TITLE, Utilities.MARK_ITEM_FORMS ) ) );
80
81 private SolrQueryService( )
82 {
83
84 }
85
86 public static SolrQuery getCommonFilteredQuery( HttpServletRequest request, Map<String, String> searchParameters,
87 Map<String, String [ ]> searchMultiParameters )
88 {
89 SolrQuery query = new SolrQuery( );
90 query.setQuery( SOLR_QUERY_ALL );
91 query.addFilterQuery( SOLR_FIELD_TYPE + ":" + SOLR_TYPE_APPOINTMENT_SLOT );
92 query.addFilterQuery( SOLR_FILTERQUERY_ALLOWED_NOW );
93 query.addFilterQuery( SOLR_FILTERQUERY_DAY_OPEN );
94 query.addFilterQuery( SOLR_FILTERQUERY_ENABLED );
95 query.addFilterQuery( SOLR_FILTERQUERY_ACTIVE );
96
97 for ( SimpleImmutableEntry<String, String> entry : EXACT_FACET_QUERIES )
98 {
99 addFacetToQuery( query, request, searchParameters, entry );
100 }
101
102 StringBuilder sbFqDaysOfWeek = new StringBuilder( );
103 String [ ] searchDays = Utilities.getSearchMultiParameter( Utilities.PARAMETER_DAYS_OF_WEEK, request, searchMultiParameters );
104 if ( ArrayUtils.isNotEmpty( searchDays ) )
105 {
106 sbFqDaysOfWeek.append( "{!tag=tag" + SOLR_FIELD_DAY_OF_WEEK + "}" + SOLR_FIELD_DAY_OF_WEEK + ":(" );
107 for ( int nDay = 0; nDay < searchDays.length; nDay++ )
108 {
109 if ( nDay > 0 )
110 {
111 sbFqDaysOfWeek.append( " OR " );
112 }
113 sbFqDaysOfWeek.append( searchDays [nDay] );
114 }
115 sbFqDaysOfWeek.append( ")" );
116 }
117 query.addFilterQuery( sbFqDaysOfWeek.toString( ) );
118 query.addFacetField( "{!ex=tag" + SOLR_FIELD_DAY_OF_WEEK + "}" + SOLR_FIELD_DAY_OF_WEEK );
119
120 String strFromDate = Utilities.getSearchParameterValue( Utilities.PARAMETER_FROM_DATE, request, searchParameters );
121 String strFromTime = Utilities.getSearchParameterValue( Utilities.PARAMETER_FROM_TIME, request, searchParameters );
122 String strToDate = Utilities.getSearchParameterValue( Utilities.PARAMETER_TO_DATE, request, searchParameters );
123 String strToTime = Utilities.getSearchParameterValue( Utilities.PARAMETER_TO_TIME, request, searchParameters );
124 LocalDateTime localDateTimeFrom = null;
125 try
126 {
127 localDateTimeFrom = LocalDateTime.parse( strFromDate + " " + strFromTime, Utilities.inputFormatter );
128 }
129 catch( DateTimeParseException e )
130 {
131 localDateTimeFrom = null;
132 }
133 String strSolrDateTimeFrom = "*";
134 if ( localDateTimeFrom != null )
135 {
136 strSolrDateTimeFrom = localDateTimeFrom.format( Utilities.outputFormatter );
137 }
138 LocalDateTime localDateTimeTo = null;
139 try
140 {
141 localDateTimeTo = LocalDateTime.parse( strToDate + " " + strToTime, Utilities.inputFormatter );
142 }
143 catch( DateTimeParseException e )
144 {
145 localDateTimeTo = null;
146 }
147 String strSolrDateTimeTo = "*";
148 if ( localDateTimeTo != null )
149 {
150 strSolrDateTimeTo = localDateTimeTo.format( Utilities.outputFormatter );
151 }
152 query.addFilterQuery( SOLR_FIELD_DATE + ":[" + strSolrDateTimeFrom + " TO " + strSolrDateTimeTo + "]" );
153 String strFromDayMinute = Utilities.getSearchParameterValue( Utilities.PARAMETER_FROM_DAY_MINUTE, request, searchParameters );
154 String strToDayMinute = Utilities.getSearchParameterValue( Utilities.PARAMETER_TO_DAY_MINUTE, request, searchParameters );
155 String strSolrDayMinuteFrom = "*";
156 if ( strFromDayMinute != null )
157 {
158 strSolrDayMinuteFrom = strFromDayMinute;
159 }
160 String strSolrDayMinuteTo = "*";
161 if ( strToDayMinute != null )
162 {
163 strSolrDayMinuteTo = strToDayMinute;
164 }
165 query.addFilterQuery( SOLR_FIELD_MINUTE_OF_DAY + ":[" + strSolrDayMinuteFrom + " TO " + strSolrDayMinuteTo + "]" );
166
167 String strNbConsecutiveSlots = Utilities.getSearchParameterValue( Utilities.PARAMETER_NB_SLOTS, request, searchParameters );
168 int nbConsecutiveSlots = Integer.parseInt( strNbConsecutiveSlots );
169 query.addFilterQuery( SOLR_NB_CONSECUTIVES_SLOTS + ":[" + nbConsecutiveSlots + " TO *]" );
170
171 String strRole = Utilities.getSearchParameterValue( Utilities.PARAMETER_ROLE, request, searchParameters );
172 if ( StringUtils.isNotEmpty( strRole ) && !"none".equals( strRole ) )
173 {
174 query.addFilterQuery( SOLR_ROLE + ":" + strRole );
175 }
176 return query;
177 }
178
179 private static void addFacetToQuery( SolrQuery query, HttpServletRequest request, Map<String, String> searchParameters,
180 SimpleImmutableEntry<String, String> entry )
181 {
182 String strValue = Utilities.getSearchParameterValue( entry.getValue( ), request, searchParameters );
183 String strFacetField;
184 if ( SOLR_FIELD_FORM_UID.equals( entry.getKey( ) ) )
185 {
186 strFacetField = SOLR_FIELD_FORM_UID_TITLE;
187 }
188 else
189 {
190 strFacetField = entry.getKey( );
191 }
192 if ( StringUtils.isNotBlank( strValue ) )
193 {
194 String strFilterQuery;
195 if ( VALUE_FQ_EMPTY.equals( strValue ) )
196 {
197 strFilterQuery = entry.getKey( ) + ":" + "\"\" OR (*:* NOT " + entry.getKey( ) + ":*)";
198 }
199 else
200 {
201 strFilterQuery = entry.getKey( ) + ":" + ClientUtils.escapeQueryChars( strValue );
202 }
203 query.addFilterQuery( "{!tag=tag" + strFacetField + "}" + strFilterQuery );
204 strFacetField = "{!ex=tag" + strFacetField + "}" + strFacetField;
205 }
206 query.addFacetField( strFacetField );
207 }
208 }