internal void ExecuteCommit() { //need to send Examine all of the stuff to index for this unit of work //we need to 'stagger' the operations as it will be much faster to send all of the "Adds" to Examine at once and then each "Delete" one at a time. //because of the way Examine works, we also need to 'stagger' the index categories as well using (DisposableTimer.TraceDuration <ExamineTransaction>("Start adding indexes to Examine queue", "End adding indexes to Examine queue")) { var examineOperations = new List <IndexOperation>(); //we track the TypedEntity revisions committed for 2 reasons (we're tracking the TypedEntity item in the revision): // 1: see below notes // 2: we need to update the status changed date if the status has in fact 'changed' since we need to reference in-memory objects as well var revisionsCommitted = new List <Tuple <TypedEntity, RevisionData> >(); //this will get all of the lazy ids generated so we can use the values // to lookup some entities. var ids = _itemsToIndex.Where(x => x.OperationType == IndexOperationType.Add).Select(x => x.Id.Value) .Concat(_itemsToIndex .Where(x => x.Fields.ContainsKey(FixedIndexedFields.EntityId) && x.OperationType == IndexOperationType.Add) .Select(x => x.Fields[FixedIndexedFields.EntityId].FieldValue.ToString())) .Distinct() .ToArray(); while (_itemsToIndex.Any()) { var op = _itemsToIndex.Last(); examineOperations.Add(_frameworkContext.TypeMappers.Map <IndexOperation>(op)); //if its a typed entity revision: // - track it so we can perform index cleanup on revisions // - check status changed dates so we can ensure they are correct if (op.IsRevision()) { revisionsCommitted.Add( EnsureCorrectStatusChangedDate(op, revisionsCommitted)); } EnsureRelationEntities(op, ids); //'dequeue' the item from the list _itemsToIndex.RemoveAt(_itemsToIndex.Count - 1); } //now we have all of the indexing operations ready, lets do it ExamineManager.PerformIndexing(examineOperations.ToArray()); //do some cleanup of the index data CleanupIndexedRevisions(revisionsCommitted); } }
public override InstallStatus TryInstall() { _examineManager.PerformIndexing(new IndexOperation() { Item = new IndexItem() { Id = "ExamineInstalled".EncodeAsGuid().ToString("N"), ItemCategory = "InstallRecord" }, Operation = IndexOperationType.Add }); return(new InstallStatus(InstallStatusType.Completed)); }
/// <summary> /// Need to do a bit of cleanup now for Revision entries to ensure that we keep the records flagged as IsLatest to a minimum. /// To do this we'll lookup all revisions in the index that are marked as IsLatest that have Ids of revisions that we've just committed /// that have a UtcModified date of less than the ones we've just committed... thankfully, Lucene has a Range query that we can /// use to do this cleanup /// </summary> /// <param name="revisionsCommitted">The revisions committed during this transaction</param> private void CleanupIndexedRevisions(IEnumerable <Tuple <TypedEntity, RevisionData> > revisionsCommitted) { foreach (var r in revisionsCommitted) { //TODO: Figure out how Lucene is dealing with DateTime and UTC... currently were putting it back a day // but if we can do an Hour that would be better, just need to figure out what it is storing. var criteria = ExamineManager.CreateSearchCriteria() .Must().EntityType <TypedEntity>() .Must().HiveId(r.Item1.Id, FixedIndexedFields.EntityId) .Must().Field(FixedRevisionIndexFields.IsLatest, "1".Escape()) .Must().Range(FixedIndexedFields.UtcModified, DateTime.MinValue, r.Item1.UtcModified.UtcDateTime.AddDays(-1)); foreach (var i in ExamineManager.Search(criteria.Compile())) { //convert the fields returned var fields = i.Fields.ToDictionary(f => f.Key, f => new ItemField(f.Value)); //remove the flag fields[FixedRevisionIndexFields.IsLatest] = new ItemField(0) { DataType = FieldDataType.Int }; //now we need to update the index item to not be latest var updateOp = new IndexOperation { Operation = IndexOperationType.Add, Item = new IndexItem { Fields = fields, Id = i.Id, ItemCategory = i.Fields[LuceneIndexer.IndexCategoryFieldName] } }; //do the update ExamineManager.PerformIndexing(updateOp); } } }