예제 #1
0
        public static void BuildIndex(FullTextIndexRebuildProc graph, RecordType item)
        {
            Debug.Print("Start processing {0}", item.Name);
            Stopwatch sw = new Stopwatch();

            graph.Caches.Clear();
            graph.Clear(PXClearOption.ClearAll);

            PXProcessing <RecordType> .SetCurrentItem(item);

            Type entity = GraphHelper.GetType(item.Entity);

            PXSearchableAttribute searchableAttribute = null;
            var list = graph.Caches[entity].GetAttributes("NoteID");

            foreach (PXEventSubscriberAttribute att in list)
            {
                PXSearchableAttribute attribute = att as PXSearchableAttribute;
                if (attribute != null)
                {
                    searchableAttribute = attribute;
                    break;
                }
            }

            if (searchableAttribute == null)
            {
                return;
            }

            Type viewType;


            Type joinNote = typeof(LeftJoin <Note, On <Note.noteID, Equal <SearchIndex.noteID> > >);

            if (searchableAttribute.SelectForFastIndexing != null)
            {
                Type noteentity = entity;
                if (searchableAttribute.SelectForFastIndexing.IsGenericType)
                {
                    Type[] tables = searchableAttribute.SelectForFastIndexing.GetGenericArguments();
                    if (tables != null && tables.Length > 0 && typeof(IBqlTable).IsAssignableFrom(tables[0]))
                    {
                        noteentity = tables[0];
                    }
                }
                Type joinSearchIndex = BqlCommand.Compose(
                    typeof(LeftJoin <,>),
                    typeof(SearchIndex),
                    typeof(On <,>),
                    typeof(SearchIndex.noteID),
                    typeof(Equal <>),
                    noteentity.GetNestedType("noteID"));

                viewType = BqlCommand.AppendJoin(searchableAttribute.SelectForFastIndexing, joinSearchIndex);
                viewType = BqlCommand.AppendJoin(viewType, joinNote);
            }
            else
            {
                Type joinSearchIndex = BqlCommand.Compose(
                    typeof(LeftJoin <,>),
                    typeof(SearchIndex),
                    typeof(On <,>),
                    typeof(SearchIndex.noteID),
                    typeof(Equal <>),
                    entity.GetNestedType("noteID"));

                viewType = BqlCommand.Compose(typeof(Select <>), entity);
                viewType = BqlCommand.AppendJoin(viewType, joinSearchIndex);
                viewType = BqlCommand.AppendJoin(viewType, joinNote);
            }

            BqlCommand cmd = BqlCommand.CreateInstance(viewType);

            PXView        itemView = new PXView(graph, true, cmd);
            List <object> resultset;

            List <Type> fieldList       = new List <Type>(searchableAttribute.GetSearchableFields(graph.Caches[entity]));
            Type        entityForNoteId = entity;

            while (typeof(IBqlTable).IsAssignableFrom(entityForNoteId))
            {
                Type tN = entityForNoteId.GetNestedType("noteID");
                if (null != tN)
                {
                    fieldList.Add(tN);
                }
                entityForNoteId = entityForNoteId.BaseType;
            }
            fieldList.Add(typeof(SearchIndex.noteID));
            fieldList.Add(typeof(SearchIndex.category));
            fieldList.Add(typeof(SearchIndex.content));
            fieldList.Add(typeof(SearchIndex.entityType));
            fieldList.Add(typeof(Note.noteID));
            fieldList.Add(typeof(Note.noteText));

            sw.Start();

            int batchSize = 50000;
            int startRow  = 0;

            do
            {
                using (new PXFieldScope(itemView, fieldList)) {
                    //resultset = itemView.SelectMulti();
                    resultset = itemView.SelectWindowed(null, null, null, null, startRow, batchSize);
                }
                sw.Stop();
                Debug.Print("{0} GetResultset in {1} sec. Total records={2}", item.DisplayName, sw.Elapsed.TotalSeconds, resultset.Count);
                sw.Reset();
                sw.Start();

                startRow += batchSize;

                int totalcount = resultset.Count;
                int cx         = 0;
                int dx         = 0;

                try {
                    Dictionary <Guid, SearchIndex> insertDict = new Dictionary <Guid, SearchIndex>(resultset.Count);
                    foreach (var res in resultset)
                    {
                        cx++;

                        bool isSearchable = searchableAttribute.IsSearchable(graph.Caches[entity], ((PXResult)res)[entity]);
                        if (isSearchable)
                        {
                            dx++;

                            Note        note = (Note)((PXResult)res)[typeof(Note)];
                            SearchIndex si   = searchableAttribute.BuildSearchIndex(graph.Caches[entity], ((PXResult)res)[entity],
                                                                                    (PXResult)res, ExtractNoteText(note));
                            SearchIndex searchIndex = (SearchIndex)((PXResult)res)[typeof(SearchIndex)];

                            if (searchIndex.NoteID != null && searchIndex.NoteID != si.NoteID)
                            {
                                PXSearchableAttribute.Delete(si);
                            }

                            if (searchIndex.NoteID == null)
                            {
                                if (!insertDict.ContainsKey(si.NoteID.Value))
                                {
                                    insertDict.Add(si.NoteID.Value, si);
                                }
                            }
                            else if (si.Content != searchIndex.Content || si.Category != searchIndex.Category ||
                                     si.EntityType != searchIndex.EntityType)
                            {
                                PXSearchableAttribute.Update(si);
                            }
                        }
                    }
                    sw.Stop();
                    Debug.Print("{0} Content building in {1} sec. Records processed = {2}. Searchable={3}", item.DisplayName, sw.Elapsed.TotalSeconds, totalcount, dx);
                    sw.Reset();
                    sw.Start();
                    PXSearchableAttribute.BulkInsert(insertDict.Values);
                    sw.Stop();
                    Debug.Print("{0} BulkInsert in {1} sec.", item.DisplayName, sw.Elapsed.TotalSeconds);
                }
                catch (Exception ex) {
                    string msg = string.Format(Messages.OutOfProcessed, cx, totalcount, dx, ex.Message);
                    throw new Exception(msg, ex);
                }
            } while (resultset.Count > 0);

            PXProcessing <RecordType> .SetProcessed();
        }