private static QueryPart DateQueryToQueryPart(string query) { // Format // query := date[-date] // date := empty | year | year.month | year.month.date // FIXME: Do we really want to query time too ? They are too long! if (query == String.Empty) { throw new FormatException(); } int next_date_index = query.IndexOf('-'); if (next_date_index == -1) { return(DateToQueryPart(query)); } // We have a range query - get the ranges DateTime start_date, end_date; try { int y, m, d; ParseDateQuery(query.Substring(0, next_date_index), out y, out m, out d); start_date = CreateDateTime(y, m, d, true); } catch (FormatException) { start_date = DateTime.MinValue; } try { int y, m, d; ParseDateQuery(query.Substring(next_date_index + 1), out y, out m, out d); end_date = CreateDateTime(y, m, d, false); } catch (FormatException) { // FIXME: Should the default end_date be DateTime.Now ? end_date = DateTime.MinValue; } if (start_date == DateTime.MinValue && end_date == DateTime.MinValue) { throw new FormatException(); } QueryPart_DateRange range_query = new QueryPart_DateRange(); range_query.Key = QueryPart_DateRange.TimestampKey; range_query.StartDate = start_date; range_query.EndDate = end_date; Log.Debug("Parsed date range query [{0}] as {1}", query, range_query); return(range_query); }
private static QueryPart_DateRange DateToQueryPart(string dt_string) { int y, m, d; ParseDateQuery(dt_string, out y, out m, out d); QueryPart_DateRange dt_query = new QueryPart_DateRange(); dt_query.Key = QueryPart_DateRange.TimestampKey; dt_query.StartDate = CreateDateTime(y, m, d, true); dt_query.EndDate = CreateDateTime(y, m, d, false); Log.Debug("Parsed date query [{0}] as {1}", dt_string, dt_query); return(dt_query); }
static private LNS.Query GetDateRangeQuery (QueryPart_DateRange part, out HitFilter hit_filter) { string field_name; if (part.Key == QueryPart_DateRange.AllPropertiesKey) field_name = TypeToWildcardField (PropertyType.Date); else if (part.Key == QueryPart_DateRange.TimestampKey) field_name = "Timestamp"; else field_name = PropertyToFieldName (PropertyType.Date, part.Key); // FIXME: We could optimize this and reduce the size of our range // queries if we actually new the min and max date that appear in // any properties in the index. We would need to inspect the index to // determine that at start-up, and then track it as new documents // get added to the index. if (part.StartDate < lower_bound) part.StartDate = lower_bound; if (part.EndDate > upper_bound || part.EndDate == DateTime.MinValue) part.EndDate = upper_bound; // Swap the start and end dates if they come in reversed. if (part.StartDate > part.EndDate) { DateTime swap; swap = part.StartDate; part.StartDate = part.EndDate; part.EndDate = swap; } // Set up our hit filter to cull out the bad dates. DateRangeHitFilter drhf; drhf = new DateRangeHitFilter (); drhf.Key = part.Key; drhf.StartDate = part.StartDate; drhf.EndDate = part.EndDate; hit_filter = new HitFilter (drhf.HitFilter); Logger.Log.Debug ("Building new date range query"); Logger.Log.Debug ("Start: {0}", part.StartDate); Logger.Log.Debug ("End: {0}", part.EndDate); int y1, m1, d1, y2, m2, d2; y1 = part.StartDate.Year; m1 = part.StartDate.Month; d1 = part.StartDate.Day; y2 = part.EndDate.Year; m2 = part.EndDate.Month; d2 = part.EndDate.Day; LNS.BooleanQuery top_level_query; top_level_query = new LNS.BooleanQuery (); // A special case: both the start and the end of our range fall // in the same month. if (y1 == y2 && m1 == m2) { LNS.Query ym_query; ym_query = NewYearMonthQuery (field_name, y1, m1); // If our range only covers a part of the month, do a range query on the days. if (d1 != 1 || d2 != DateTime.DaysInMonth (y2, m2)) { LNS.BooleanQuery sub_query; sub_query = new LNS.BooleanQuery (); sub_query.Add (ym_query, LNS.BooleanClause.Occur.MUST); sub_query.Add (NewDayQuery (field_name, d1, d2), LNS.BooleanClause.Occur.MUST); top_level_query.Add (sub_query, LNS.BooleanClause.Occur.SHOULD); } else { top_level_query.Add (ym_query, LNS.BooleanClause.Occur.SHOULD); } } else { // Handle a partial month at the beginning of our range. if (d1 > 1) { LNS.BooleanQuery sub_query; sub_query = new LNS.BooleanQuery (); sub_query.Add (NewYearMonthQuery (field_name, y1, m1), LNS.BooleanClause.Occur.MUST); sub_query.Add (NewDayQuery (field_name, d1, DateTime.DaysInMonth (y1, m1)), LNS.BooleanClause.Occur.MUST); top_level_query.Add (sub_query, LNS.BooleanClause.Occur.SHOULD); ++m1; if (m1 == 13) { m1 = 1; ++y1; } } // And likewise, handle a partial month at the end of our range. if (d2 < DateTime.DaysInMonth (y2, m2)) { LNS.BooleanQuery sub_query; sub_query = new LNS.BooleanQuery (); sub_query.Add (NewYearMonthQuery (field_name, y2, m2), LNS.BooleanClause.Occur.MUST); sub_query.Add (NewDayQuery (field_name, 1, d2), LNS.BooleanClause.Occur.MUST); top_level_query.Add (sub_query, LNS.BooleanClause.Occur.SHOULD); --m2; if (m2 == 0) { m2 = 12; --y2; } } // Generate the query for the "middle" of our period, if it is non-empty if (y1 < y2 || ((y1 == y2) && m1 <= m2)) top_level_query.Add (NewYearMonthQuery (field_name, y1, m1, y2, m2), LNS.BooleanClause.Occur.SHOULD); } return top_level_query; }
static private Query NewRandomQuery(int length, bool allow_inexpensive, bool inside_an_or) { Query query; query = new Query(); // One in four queries will contain some OR terms. if (!inside_an_or && random.Next(4) == 0) { int N = random.Next(3) + 1; for (int i = 0; i < N; ++i) { QueryPart_Or part; part = new QueryPart_Or(); int sub_length; sub_length = random.Next(length) + 1; if (sub_length < 2) { sub_length = 2; } // We generate a new query at random, and stuff its QueryParts // into our Or QueryPart. Query or_query; or_query = NewRandomQuery(sub_length, allow_inexpensive, true); foreach (QueryPart sub_part in or_query.Parts) { part.Add(sub_part); } query.AddPart(part); } } if (allow_inexpensive && !inside_an_or) { int mime_type; mime_type = random.Next(3); QueryPart_Or mime_type_part = new QueryPart_Or(); QueryPart_Property part; part = new QueryPart_Property(); part.Type = PropertyType.Keyword; part.Key = "beagle:MimeType"; if (mime_type == 0) { part.Value = "inode/directory"; mime_type_part.Add(part); query.AddPart(mime_type_part); } else if (mime_type == 1) { part.Value = "text/plain"; mime_type_part.Add(part); query.AddPart(mime_type_part); } } // Every query must contain at least // one required part. bool contains_required; contains_required = false; for (int i = 0; i < length; ++i) { QueryPart_Text part; part = new QueryPart_Text(); part.Text = Token.GetRandom(); // Prohibited parts are not allowed inside an or if (contains_required && !inside_an_or) { if (random.Next(2) == 0) { part.Logic = QueryPartLogic.Prohibited; } } else { // This part will be required. contains_required = true; } if (random.Next(2) == 0) { part.SearchTextProperties = false; } else if (allow_inexpensive && random.Next(2) == 0) { part.SearchFullText = false; } query.AddPart(part); } // Note the ! inside_an_or; date range queries don't // work right inside OR queries when being searched // within the resolution of one day. See the FIXME // about hit filters in LuceneCommon.cs if (allow_inexpensive && !inside_an_or && random.Next(3) == 0) { DateTime a, b; FileSystemObject.PickTimestampRange(out a, out b); QueryPart_DateRange part; part = new QueryPart_DateRange(); part.StartDate = a; part.EndDate = b; query.AddPart(part); } return(query); }
private static QueryPart_DateRange DateToQueryPart (string dt_string) { int y, m, d; ParseDateQuery (dt_string, out y, out m, out d); QueryPart_DateRange dt_query = new QueryPart_DateRange (); dt_query.Key = QueryPart_DateRange.TimestampKey; dt_query.StartDate = CreateDateTime (y, m, d, true); dt_query.EndDate = CreateDateTime (y, m, d, false); Log.Debug ("Parsed date query [{0}] as {1}", dt_string, dt_query); return dt_query; }
private static QueryPart DateQueryToQueryPart (string query) { // Format // query := date[-date] // date := empty | year | year.month | year.month.date // FIXME: Do we really want to query time too ? They are too long! if (query == String.Empty) throw new FormatException (); int next_date_index = query.IndexOf ('-'); if (next_date_index == -1) return DateToQueryPart (query); // We have a range query - get the ranges DateTime start_date, end_date; try { int y, m, d; ParseDateQuery (query.Substring (0, next_date_index), out y, out m, out d); start_date = CreateDateTime (y, m, d, true); } catch (FormatException) { start_date = DateTime.MinValue; } try { int y, m, d; ParseDateQuery (query.Substring (next_date_index + 1), out y, out m, out d); end_date = CreateDateTime (y, m, d, false); } catch (FormatException) { // FIXME: Should the default end_date be DateTime.Now ? end_date = DateTime.MinValue; } if (start_date == DateTime.MinValue && end_date == DateTime.MinValue) throw new FormatException (); QueryPart_DateRange range_query = new QueryPart_DateRange (); range_query.Key = QueryPart_DateRange.TimestampKey; range_query.StartDate = start_date; range_query.EndDate = end_date; Log.Debug ("Parsed date range query [{0}] as {1}", query, range_query); return range_query; }