Question
· Oct 18, 2017

Rebuild class index

I have a class. In class there is an index. This index is for quick search on name property.

Class User
{

.....

Property Name as %String;

Index NameInd On Name;

.....

}

This class is mapped to some global ^GL(userId) = "Name*other data....****"

And there is also index global ^GLNameIndex(Name, userId) = ""

When I add new User entry through class, f. i.

S user = ##class(User).%New()
S user.Name = "Some name"
​D user.%Save()

calling method %Save() adding new entry to index automatically.

And this way index ^GLNameIndex is always actual.

But in my program new user entry can be added without class interface, through terminal program.

In terminal program new user entry is added by direct recording to global, f. i. 

S ^GL(userId) = "Name*other data."

In this case, new user name is not adding to index global ^GLNameIndex and index is not actual.

How should I resolve this case, when new user adding without class interface? Should I manually adding new user name to index global or there is some class method for rebuilding index?

Method  persistent.%BuildIndices() rebuild all entries, but I need to add only one new entry to index.

Discussion (6)0
Log in or sign up to continue

I have two different ways for creating new objects because of there are two different interfaces in the program. There is old interface via terminal with direct access to globals and there is new zen web interface with classes.

And some users prefer to work with old terminal interface, so I must to maintain also the old inteface.

Can you give me some example with  %FileIndices? I didn't find anything 

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.SearchPageZen...

Hi!

The method %FileIndices(id) may help you. The problem is that you won't know which ID you must use to call it. Have new objects been added? Which have been changed?

I assume you have taken an old style global and mapped it to classes and have created an index for it. That's ok. Normally old style applications will have its own indices on the same global or another. They probably have an index on Name already that they use and you should try to map that existing subscript as your name index on your mapped class instead of creating a new index.

But if you really want to go on and create a new index, you have only two choices:

  1. To change the old style code to use objects/sql and stop setting the globals directly for that specific entity
  2. To change the old style code to set the new index global together with the data global (this is very common practice on old style applications).
  3. Ask them (the programmers of the old style application) to call %FileIndices(id) themselves after adding/changing a record so that all the indices defined on your mapped class would be (re)computed (including the indices that they have already set manually and you have mapped on your class). You could offer them to call this method to populate the indices global for them instead of setting the indices globals themselves to eliminate the redundant work. But you would have to have your mappings very well defined to replace their code, with all their indices.

As you can see, all options imply changing the old style code. I would push for option number 1 as this can be the start of some real good improvements to your old style application. 

There is no middle ground here, unless you want to rebuild all your indices every day.

Depending on how many places this global is referred on your application, the way the application is compartmentalized, and if you are using indirection or not throughout your application, these changes can be very simple or very complex to do and test.

Another way of going about this is to try to use the journals APIs to read the journal files, detect changes on this specific global and update the index... That would prevent you from touching the old style application. I have never done this before, but I believe it is pretty feasible.

Kind regards,

AS