private static void SetLocationAsDoubleField(Examine.LuceneEngine.DocumentWritingEventArgs e) { //Get existing field - some members may not have a valueset - so check in case //Oddly some members only have one field set?! if (e.Fields.ContainsKey("latitude") == false || e.Fields.ContainsKey("longitude") == false) { return; } var existingLatField = e.Document.GetField("latitude"); var existingLonField = e.Document.GetField("longitude"); //More sanity checking if (existingLatField != null && existingLonField != null) { try { var latitude = Convert.ToDouble(existingLatField.StringValue()); var longitude = Convert.ToDouble(existingLonField.StringValue()); var latNumnber = new NumericField("latitudeNumber", Field.Store.YES, true).SetDoubleValue(latitude); var lonNumnber = new NumericField("longitudeNumber", Field.Store.YES, true).SetDoubleValue(longitude); e.Document.Add(latNumnber); e.Document.Add(lonNumnber); } catch (Exception ex) { var message = $"Unable to cast lat or lon to a double. Attempted to convert Lat:'{existingLatField.StringValue()}' Lon:'{existingLonField.StringValue()}' for Member ID: '{e.NodeId}'"; LogHelper.Error <MapEventHandler>(message, ex); } } }
/// <summary> /// Event handler to create a lower cased version of the node name, this is so we can support case-insensitive searching and still /// use the Whitespace Analyzer. This also ensures the 'Raw' values are added to the document. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void IndexerDocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { //This ensures that the special __Raw_ fields are indexed var d = e.Document; foreach (var f in e.Fields.Where(x => x.Key.StartsWith(RawFieldPrefix))) { d.Add(new Field( f.Key, f.Value, Field.Store.YES, Field.Index.NO, //don't index this field, we never want to search by it Field.TermVector.NO)); } //add the lower cased version if (e.Fields.Keys.Contains("nodeName")) { e.Document.Add(new Field("__nodeName", e.Fields["nodeName"].ToLower(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO )); } }
static void ExamineEventsHandler_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { var indexer = sender as BaseIndexProvider; if (indexer == null) { return; } foreach (var examineEventsConsumer in _examineEventsConsumers) { if (examineEventsConsumer.AppliedIndexes.Contains(indexer.Name)) { try { examineEventsConsumer.OnDocumentWriting(e); } catch (Exception exception) { LogHelper.Error <ExamineEventsHandler>("Error With Event Consumer", exception); } } } }
/// <summary> /// Event handler to create a lower cased version of the node name, this is so we can support case-insensitive searching and still /// use the Whitespace Analyzer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void indexer_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { if (e.Fields.Keys.Contains("nodeName")) { //add the lower cased version e.Document.Add(new Field("__nodeName", e.Fields["nodeName"].ToLower(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO )); } }
/// <summary> /// Required to sort blog posts using Examine. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Indexer_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { const string dateField = "postDate"; DateTime reviewDate; if (e.Fields.ContainsKey(dateField)) { reviewDate = DateTime.Parse(e.Fields[dateField]); } else { reviewDate = DateTime.Parse(e.Fields["updateDate"]); } var field = new Field("__Sort_" + dateField, reviewDate.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NOT_ANALYZED); e.Document.Add(field); }
void indexer_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { const string dateField = "reviewDate"; DateTime articleDate; if (e.Fields.ContainsKey(dateField)) { articleDate = DateTime.Parse(e.Fields[dateField]); } else { articleDate = DateTime.Parse(e.Fields["updateDate"]); } // in __Sort_articleDate the __ implies is not analysed therefore can be used to sorting. sorted means its retrievable //see page 43 lucene in action 2nd edition for full explanation of options var field = new Field("__Sort_" + dateField, articleDate.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NOT_ANALYZED); e.Document.Add(field); }
private static void SetKarmaAsNumericField(Examine.LuceneEngine.DocumentWritingEventArgs e) { //Get existing field karma field - some members may not have a value set - so check in case var existingField = e.Document.GetField("reputationCurrent"); if (existingField != null) { //Add new field that is numeric & prefix with the magic '__Sort_' string var karmaField = new NumericField(LuceneIndexer.SortedFieldNamePrefix + "karma", Field.Store.YES, true); //Get the existing value that is stored on the vanilla property that stores as strings var existingValue = existingField.StringValue(); //Convert to int var valAsInt = Convert.ToInt32(existingValue); //Set it on the karma field karmaField.SetIntValue(valAsInt); //Add the field to the document e.Document.Add(karmaField); } }
private void Indexer_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { SetKarmaAsNumericField(e); SetLocationAsDoubleField(e); }
private static void DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { var indexer = (BaseUmbracoIndexer)sender; foreach (var field in indexer.IndexerData.UserFields) { if (e.Fields.ContainsKey(field.Name)) { if (e.Fields[field.Name].DetectIsJson()) { try { //TODO: We should deserialize this to Umbraco.Core.Models.GridValue instead of doing the below var json = JsonConvert.DeserializeObject <JObject>(e.Fields[field.Name]); //check if this is formatted for grid json JToken name; JToken sections; if (json.HasValues && json.TryGetValue("name", out name) && json.TryGetValue("sections", out sections)) { //get all values and put them into a single field (using JsonPath) var sb = new StringBuilder(); foreach (var row in json.SelectTokens("$.sections[*].rows[*]")) { var rowName = row["name"].Value <string>(); var areaVals = row.SelectTokens("$.areas[*].controls[*].value"); foreach (var areaVal in areaVals) { //TODO: If it's not a string, then it's a json formatted value - // we cannot really index this in a smart way since it could be 'anything' if (areaVal.Type == JTokenType.String) { var str = areaVal.Value <string>(); str = XmlHelper.CouldItBeXml(str) ? str.StripHtml() : str; sb.Append(str); sb.Append(" "); //add the row name as an individual field e.Document.Add( new Field( string.Format("{0}.{1}", field.Name, rowName), str, Field.Store.YES, Field.Index.ANALYZED)); } } } if (sb.Length > 0) { //First save the raw value to a raw field e.Document.Add( new Field( string.Format("{0}{1}", UmbracoContentIndexer.RawFieldPrefix, field.Name), e.Fields[field.Name], Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO)); //now replace the original value with the combined/cleaned value e.Document.RemoveField(field.Name); e.Document.Add( new Field( field.Name, sb.ToString(), Field.Store.YES, Field.Index.ANALYZED)); } } } catch (InvalidCastException) { //swallow...on purpose, there's a chance that this isn't the json format we are looking for // and we don't want that to affect the website. } catch (JsonException) { //swallow...on purpose, there's a chance that this isn't json and we don't want that to affect // the website. } catch (ArgumentException) { //swallow on purpose to prevent this error: // Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject. } } } } }