Meine Adresse ist kein Haus oder eine Straße, meine Adresse ist die Sowjetunion?

microBIGDATA oder FIAS in der Tasche


Peter Brueghel der Jüngere, Steuerzahlung , 1640

Der letzte Eintrag auf dem Rasierer auf den Objekten ging. Wir werden die Aufklärung im Kampf fortsetzen. Heute werden wir über das Schwierige sprechen. Es geht noch nicht um GROSSE DATEN, aber es ist bereits unpraktisch zu arbeiten - große Datenmengen. Nicht jeder passt in den gesamten Arbeitsspeicher, aber einige passen nicht einmal auf die Festplatte (es gibt nicht genügend Speicherplatz, aber viel Müll). Der Name unserer vertrauenswürdigen FIAS-Datenbank ist die Datenbank des Bundesadressinformationssystems . 5,5 GB Archiv. Und es wird in ein XML-Archiv komprimiert. Nach dem Auspacken stehen volle 53 GB zur Verfügung (110 GB zum Auspacken aufbewahren). Und wenn Sie anfangen, es zu analysieren und zu konvertieren, reichen 110 GB nicht aus. Über die erforderliche Menge an RAM wird auch sein.

Alles wäre gut, aber Sie können weiter graben. Es gibt ein solches internationales Open-Source-Projekt zur Datenerfassung und -systematisierung - OpenAddresses . Es wird also mehr Datenbanken geben. Die aktuelle Abdeckung des Planeten hat viele weiße Flecken, zum Beispiel fehlt Russland fast. Die Archivgröße beträgt 10 GB.

Oder eine Datenbank eines ziemlich bekannten OpenStreetMaps-Projekts . Es wird von Freiwilligen auf Basis von Wikipedia gebaut. Ziemlich detailliert und mehrsprachig. Jetzt ein komplettes Archiv komprimierten XML mit einer Größe von 74 GB.
Wenn sie anfingen, über Adressen zu sprechen, kamen rechtzeitig unerwartete Nachrichten von DuckDuckGo , der besten sicheren Suchmaschine für heute, über den Übergang zu Apple-Karten. Genauer gesagt auf Apple MapKit JS. Das interessanteste Merkmal in unserem Kontext ist die „verbesserte Adressensuche“. Ist Apple das beste Unternehmen, das unsere Daten sorgfältig sammelt und schützt? Es wird notwendig sein, ...
Also die Herausforderung. Wie Sie all diesen Adressreichtum in ein angenehmes Repository stellen, damit Sie von einer kostenlosen API träumen können (natürlich in Python) und Ihr liebes Eisen nicht an einer ungelesenen Ladung ersticken darf. Nennen wir es MicroBigData - mcBD oder μBG auf Englisch :-)

In der Wirtschaft eines jeden zweiten (oder sogar des ersten) Entwicklers ist dieses Ding ein Adressverzeichnis, es ist auch ein Verzeichnis von Toponymen, eine Sache, die sehr notwendig ist. Und wenn es auch normativ, vorbereitet, gereinigt und vom richtigen Körper gut dokumentiert ist, ist es nur ein Märchen. Wir müssen Tribut zollen, der russische Steuerdienst macht seine digitale Produktion gut. So weit wie möglich. Es gibt wahrscheinlich einige Fehler im Inneren und die Datenbereinigung wird fortgesetzt. Lassen Sie die Staatsoberhäupter nachdenken, wie Sie dieses Problem lösen können. Sie entscheiden für uns und zum Nutzen von uns allen. Übrigens wurde im folgenden Beispiel ein Tippfehler von FIAS gefunden. Das Ergebnis ist nicht betroffen. Ich habe es nicht repariert. Wirst du finden?

Ich weiß nicht, wie spezifisch die Adressdaten in Ihren Projekten relevant sind - dies sind alles Regionen, Städte, Straßen. Aber es scheint, dass kein einziges Projekt für Menschen ohne sie auskommen kann. Dies ist die Adresse, an der eine Person gesucht oder Pakete an sie gesendet werden sollen. Diese Details des Passes oder eines anderen Dokuments müssen gespeichert werden. Oder vielleicht ist es die Adresse des Arbeitsbüros oder der Sehenswürdigkeiten, die zu besuchen empfohlen werden. Und was machen? Wo zu bekommen

Die einfachste Lösung, ohne Rücksicht auf Fehler und Duplikate, sind primitive Objekte, die einfache Zeichenfolgenliterale enthalten (sie sind Zeichenfolgenkonstanten, sie sind auch Zeichenfolgen). Lassen Sie Benutzer die nächsten empfangenen Einträge eingeben. Und die Objekte können sich selbst retten - das haben wir bereits bestanden .

Solche Objekte sind beispielsweise wie in der folgenden Klasse beschrieben. Direkt aus dem Lehrbuch , wenn auch amerikanisch, aber angepasst an unsere russische Realität - anstelle ihrer Postleitzahl wird es unseren Postleitzahl geben. Ich würde auch die Postleitzahl durch eine Nummer ersetzen, aber aus Gründen der Monotonie hinterlasse ich eine Zeichenfolge. Jeder, der eine Sprache sofort erkennt und dies ist ObjectScript, hat Anspruch auf ein ermutigendes Like.

Class Soviet.Address Extends %Persistent { Property streetName As %String; Property cityName As %String; Property areaName As %String; Property postalCode As %String; } 

Natürlich werden viele empört sein, sie sagen, dass alles aus den Taschen des Objekts ragt (Literale). Wo wurde es gesehen, damit das Objekt seine Felder öffentlich beleuchtet?! Lassen wir es so, es tut auch einem beredten Beispiel weh und ist für jeden Schüler verständlich.

Das ist eigentlich alles was benötigt wird. In den Feldern ausgefüllt. Einlagern. Zur Arbeit auf andere Objekte übertragen. Weiter an jemanden vererbt. Alles arbeitet. Und gespeichert!
Aber ein paar Worte, warum dies nicht wert ist, müssen gesagt werden. Wie lautet unsere Objektadresse? Warum kann es nicht einfach eine Gruppe von Textzeichenfolgen sein? Die offensichtlichsten Einwände, die mir in den Sinn kommen, kommen aus dem Kontext - wer verwendet diese Adresse in welcher Form und zu welchem ​​Zweck? Versuchen Sie, Ihr Programmierdenken beiseite zu legen und stellen Sie sich vor, wie ein „ausländischer Tourist“, ein „Historiker“, ein „Steuerinspektor“, ein „Anwalt“ usw. denken.

Ich glaube, dass sich sofort eine Reihe zusätzlicher Fragen und Klarstellungen ergeben: Welche Sprache muss verwendet werden, in welcher Codierung muss gespeichert und gegeben werden, in welcher Zeit muss klassifiziert werden, welche Dokumente werden in Kraft gesetzt, legal oder postalisch? Ist eine Stadt eine benannte Siedlung oder was? Sogar eine Straße kann sich als Boulevard, Seitenstraße, Allee oder etwas anderes herausstellen. Was tun mit all diesen wichtigen Implementierungsdetails?

Nehmen Sie ein lebendiges Beispiel. Google wird jetzt von Sundar Pichai betrieben. Er selbst kommt aus Indien. Geboren in der Stadt Chennai (auch bekannt als Chennai). Oder in Madras? 1996 entschieden die Indianer, dass der Name der Stadt sehr portugiesisch war und benannten die Hauptstadt von Tamil Nadu von Madras nach Chennai um. Und was sollen Sundar und 72 Millionen seiner Landsleute in seine elektronischen Dokumente schreiben?

Im Allgemeinen befasst sich die gesamte Wissenschaft mit dieser angewandten Toponymie .
Also betteln Fragen. Wie gehe ich mit Uhrzeit und Datum um ? Ist Geld so offensichtlich ? Sind geografische Koordinaten so einfach? Und wie ist das in Ihrem Code implementiert? Können Sie auf das ausgewählte DBMS übertragen, ohne die Abstraktionsebene zu verringern? Wie kann man nicht in atomare Arten von Maschinendaten schlüpfen und ständig über deren Rekonstruktion nachdenken? Hier lohnt es sich, nach der Quelle einer primitiven oder umgekehrt soliden API zu suchen. Denken Sie nach Belieben darüber nach.

Kurz gesagt, der Kontext ist das Wichtigste. Und das Objektmodell ermöglicht es uns, es direkt durch die Kapselung von „Maschinendaten“ und die Implementierung von kontextsensitivem „Live“ -Verhalten zu verwenden. Überhaupt nicht die niedrigen Tupel, die in Tabellen angeordnet sind ;-)

Kehren wir in der Zwischenzeit zur "primitiven" Implementierung zurück und verkomplizieren wir unser Leben. Beseitigen Sie zunächst Fehler und Duplikate. Das heißt, wir werden nach einer Möglichkeit suchen, Adressen sofort zu schreiben. Gleichzeitig helfen wir den Entwicklern der Benutzeroberfläche, Tipps für Benutzer beim Ausfüllen von Dateneingabefeldern zu organisieren.
Wenn sich zwei Personen an einem Ort versammeln - Texte und die InterSystems IRIS-Datenplattform - hat der Entwickler die echte Möglichkeit, die Bereitstellung vollständig durchzuführen, ohne die Maschine zu verlassen. Verwenden Sie beispielsweise die integrierten Objektkomponenten iKnow und iFind . Dies sind Komponenten für die Arbeit mit unstrukturierten Daten bzw. für die Volltextsuche . Russisch wird "out of the box" unterstützt.
Als erstes werden wir der Adresse beibringen, die erforderlichen Daten aus der Originalquelle zu lesen. Glücklicherweise enthält der Datensatz des Bundessteuerdienstes vorgefertigte Beschreibungen der Struktur von XML-Dokumenten. Gemäß der Beschreibung , die den Daten von der FIAS-Website beigefügt ist, benötigen wir den ADDROBJ-Datensatz, der in meinem Fall der Datei AS_ADDROBJ_2_250_01_04_01_01.xsd entspricht

Als Nächstes verwenden wir den Systemkonverter der XSD-Vorlage für die entsprechende Feldstruktur der% XML.Adaptor-Klasse, die freundlicherweise von den IRIS-Entwicklern für uns vorbereitet wurde. Das Prozentzeichen am Anfang bedeutet nur, dass dies eine Klasse aus der Systembibliothek ist. Einzelheiten zur Verwendung finden Sie in der Dokumentation . Wir werden Operationen im Terminal durchführen.

 set xmlScheme = ##class(%XML.Utils.SchemaReader).%New() do xmlScheme.Process("http://localhost/AS_ADDROBJ_2_250_01_04_01_01.xsd") 

Dasselbe kann in der Atelier-IDE (im Menü Extras> Add-Ins> XML-Schema-Assistent) oder durch ähnliche Anforderungen an Objekte direkt aus dem Programmcode abgerufen werden.



Da wir den Konstruktor verwendet haben, ohne die Parameter anzugeben, nämlich den Namen des Pakets zum Platzieren der resultierenden Klassen, sind sie im Testpaket gelandet. Wie Sie dem zweiten Befehl entnehmen können, habe ich die Schemadatei über meinen lokalen Webserver in Python übergeben:

 python3 -m http.server 80 

Sie können jeden anderen http-Server verwenden, den Sie mögen. Oder laden Sie die Datei auf Ihren IRIS-Server hoch und geben Sie den direkten Pfad dazu an.

Daher haben wir zwei Klassen, die die Struktur unseres adressierbaren XML vollständig widerspiegeln:

Test.AddressObjects
 ///            Class Test.AddressObjects Extends (%Persistent, %XML.Adaptor) [ ProcedureBlock ] { Parameter XMLNAME = "AddressObjects"; Parameter XMLSEQUENCE = 1; ///    Relationship Object As Test.Object(XMLNAME = "Object", XMLPROJECTION = "ELEMENT") [ Cardinality = many, Inverse = AddressObjects ]; } 

Testobjekt
 ///  : http://localhost:28869/AS_ADDROBJ_2_250_01_04_01_01.xsd Class Test.Object Extends (%Persistent, %XML.Adaptor) [ ProcedureBlock ] { Parameter XMLNAME = "Object"; Parameter XMLSEQUENCE = 1; ///      Property AOGUID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "AOGUID", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property FORMALNAME As %String(MAXLEN = 120, MINLEN = 1, XMLNAME = "FORMALNAME", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property REGIONCODE As %String(MAXLEN = 2, MINLEN = 2, XMLNAME = "REGIONCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property AUTOCODE As %String(MAXLEN = 1, MINLEN = 1, XMLNAME = "AUTOCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property AREACODE As %String(MAXLEN = 3, MINLEN = 3, XMLNAME = "AREACODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property CITYCODE As %String(MAXLEN = 3, MINLEN = 3, XMLNAME = "CITYCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///    Property CTARCODE As %String(MAXLEN = 3, MINLEN = 3, XMLNAME = "CTARCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///    Property PLACECODE As %String(MAXLEN = 3, MINLEN = 3, XMLNAME = "PLACECODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///     Property PLANCODE As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "PLANCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property STREETCODE As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "STREETCODE", XMLPROJECTION = "ATTRIBUTE"); ///     Property EXTRCODE As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "EXTRCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///      Property SEXTCODE As %String(MAXLEN = 3, MINLEN = 3, XMLNAME = "SEXTCODE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property OFFNAME As %String(MAXLEN = 120, MINLEN = 1, XMLNAME = "OFFNAME", XMLPROJECTION = "ATTRIBUTE"); ///   Property POSTALCODE As %String(MAXLEN = 6, MINLEN = 6, XMLNAME = "POSTALCODE", XMLPROJECTION = "ATTRIBUTE"); ///    Property IFNSFL As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "IFNSFL", XMLPROJECTION = "ATTRIBUTE"); ///      Property TERRIFNSFL As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "TERRIFNSFL", XMLPROJECTION = "ATTRIBUTE"); ///    Property IFNSUL As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "IFNSUL", XMLPROJECTION = "ATTRIBUTE"); ///      Property TERRIFNSUL As %String(MAXLEN = 4, MINLEN = 4, XMLNAME = "TERRIFNSUL", XMLPROJECTION = "ATTRIBUTE"); /// OKATO Property OKATO As %String(MAXLEN = 11, MINLEN = 11, XMLNAME = "OKATO", XMLPROJECTION = "ATTRIBUTE"); /// OKTMO Property OKTMO As %String(MAXLEN = 11, MINLEN = 8, XMLNAME = "OKTMO", XMLPROJECTION = "ATTRIBUTE"); ///    Property UPDATEDATE As %Date(XMLNAME = "UPDATEDATE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///     Property SHORTNAME As %String(MAXLEN = 10, MINLEN = 1, XMLNAME = "SHORTNAME", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///    Property AOLEVEL As %Integer(XMLNAME = "AOLEVEL", XMLPROJECTION = "ATTRIBUTE", XMLTotalDigits = 10) [ Required ]; ///     Property PARENTGUID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "PARENTGUID", XMLPROJECTION = "ATTRIBUTE"); ///   .  . Property AOID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "AOID", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///        Property PREVID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "PREVID", XMLPROJECTION = "ATTRIBUTE"); ///        Property NEXTID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "NEXTID", XMLPROJECTION = "ATTRIBUTE"); ///           4.0. Property CODE As %String(MAXLEN = 17, MINLEN = 0, XMLNAME = "CODE", XMLPROJECTION = "ATTRIBUTE"); ///      4.0      (  ) Property PLAINCODE As %String(MAXLEN = 15, MINLEN = 0, XMLNAME = "PLAINCODE", XMLPROJECTION = "ATTRIBUTE"); ///     .     .      . /// 0 –   /// 1 -  Property ACTSTATUS As %Integer(XMLNAME = "ACTSTATUS", XMLPROJECTION = "ATTRIBUTE", XMLTotalDigits = 10) [ Required ]; ///   Property CENTSTATUS As %Integer(XMLNAME = "CENTSTATUS", XMLPROJECTION = "ATTRIBUTE", XMLTotalDigits = 10) [ Required ]; ///     –    (.   OperationStatus): /// 01 – ; /// 10 – ; /// 20 – ; /// 21 –  ; /// 30 – ; /// 31 -     ; /// 40 –    (); /// 41 –     ; /// 42 -        ; /// 43 -         ; /// 50 – ; /// 51 –     ; /// 60 –    ; /// 61 –        Property OPERSTATUS As %Integer(XMLNAME = "OPERSTATUS", XMLPROJECTION = "ATTRIBUTE", XMLTotalDigits = 10) [ Required ]; ///    4 (    ) Property CURRSTATUS As %Integer(XMLNAME = "CURRSTATUS", XMLPROJECTION = "ATTRIBUTE", XMLTotalDigits = 10) [ Required ]; ///    Property STARTDATE As %Date(XMLNAME = "STARTDATE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///    Property ENDDATE As %Date(XMLNAME = "ENDDATE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///      Property NORMDOC As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "NORMDOC", XMLPROJECTION = "ATTRIBUTE"); ///     Property LIVESTATUS As %xsd.byte(VALUELIST = ",0,1", XMLNAME = "LIVESTATUS", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///  : /// 0 -   /// 1 - ; /// 2 - - Property DIVTYPE As %xsd.int(VALUELIST = ",0,1,2", XMLNAME = "DIVTYPE", XMLPROJECTION = "ATTRIBUTE") [ Required ]; Relationship AddressObjects As Test.AddressObjects(XMLPROJECTION = "NONE") [ Cardinality = one, Inverse = Object ]; } 


Aus der gesamten Liste der XML-Dateien in FIAS verwenden wir nur eine Datei mit den Namen von Regionen, Städten und Straßen. Zum Zeitpunkt der Vorbereitung der Veröffentlichung hatte ich Folgendes:
AS_ADDROBJ_20190106_90809714-fe22-45b2-929c-52bd950963e0.XML

Die Dateigröße ist weder groß noch klein, sondern fast 3 GB. Sie werden es nicht mit normalen Textwerkzeugen öffnen - sie verdauen diese Größe nicht.
Die maximale Länge eines String-Literal (String-Typ) in InterSystems IRIS beträgt übrigens nicht mehr als 3.641.144 Zeichen. Das heißt, das direkte Herunterladen der Datei oder der URL schlägt fehl. Weitere Einschränkungen finden Sie in der Dokumentation . Um mit großen Datenmengen zu arbeiten, können Sie Datenströme (Streams) verwenden, für die es keine solche Längenbeschränkung gibt.
Mal sehen, was wir bekommen?

FIAS gefüllter Pfeffer kochen. Dies ist nur eine Vorbereitung auf eine wunderbare Zukunft. Zuerst erhalten wir den anfänglichen Mindestsatz. Wir brauchen nur diese Zutaten:

 Class FIAS.AddressObject Extends (%Persistent, %XML.Adaptor) [ ProcedureBlock ] { Parameter XMLNAME = "Object"; Parameter XMLSEQUENCE = 1; ///      Property AOGUID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "AOGUID", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///   Property OFFNAME As %String(MAXLEN = 120, MINLEN = 1, XMLNAME = "OFFNAME", XMLPROJECTION = "ATTRIBUTE"); ///   Property POSTALCODE As %String(MAXLEN = 6, MINLEN = 6, XMLNAME = "POSTALCODE", XMLPROJECTION = "ATTRIBUTE"); ///     Property SHORTNAME As %String(MAXLEN = 10, MINLEN = 1, XMLNAME = "SHORTNAME", XMLPROJECTION = "ATTRIBUTE") [ Required ]; ///    Property AOLEVEL As %Integer(XMLNAME = "AOLEVEL", XMLPROJECTION = "ATTRIBUTE", XMLTotalDigits = 10) [ Required ]; ///     Property PARENTGUID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "PARENTGUID", XMLPROJECTION = "ATTRIBUTE"); ///   .  . Property AOID As %String(MAXLEN = 36, MINLEN = 36, XMLNAME = "AOID", XMLPROJECTION = "ATTRIBUTE") [ Required ]; 

Als nächstes schreiben Sie . Wir erstellen ein Objekt, das XML als nativ versteht. Wir verwenden eine Klasse aus der Systembibliothek% XML.Reader:

 set reader = ##class(%XML.Reader).%New() 

Und wir geben ihm Anweisungen, wen er nehmen soll, und ignorieren den Rest. Wir nehmen eine Portion:

 do reader.Correlate("Object","FIAS.AddressObject") 

Dann gibt es Variationen, wie man die ursprüngliche microbd-Datei erhält. Wenn es Ihnen passt, können Sie es neben das Repository stellen - lokal im Dateisystem des IRIS-Servers. Oder fragen Sie wie in meinem Beispiel nach dem Senden über HTTP. Es gibt eine noch universellere Option, die im Folgenden einige Worte enthält.

 set url="http://localhost/AS_ADDROBJ_20190106_90809714-fe22-45b2-929c-52bd950963e0.XML" write reader.OpenUrl(url) 

Wichtig! In diesem Moment wird die Mehrheit, die dieses Beispiel an sich selbst weitergeben wird, eine schreckliche Sache haben. Das System kehrt anstelle der freudigen „1“ zurück (alles ist in Ordnung), was mit „0 ¸ STORE ...“ beginnt. Und es wird nicht gefallen. Das heißt, die Datei mit einer scheinbar mikrobasierten Basis ist nicht ganz mikro und passt nicht in unser Objekt. Der ihm zugewiesene Speicher reichte nicht aus. Lösbar? Natürlich. Mit der IRIS-Datenplattform können Sie Objekte mit bis zu 4 TB im RAM erstellen. Was ist dann schief gelaufen? Standardmäßig sind die Systemeinstellungen auf 256 MB pro Objekt festgelegt. Und wir würden viel mehr brauchen. Und denken Sie daran, dies sind RAM-Anforderungen. Ist auf Ihrem Computer / Server genügend Vorrat vorhanden?
Welche Speichergröße wir benötigen, um diesen Riesen zu installieren, haben wir empirisch installiert - fast 10 GB. Was müssen Sie in den Einstellungen (Menü> Speicher konfigurieren> Maximaler Speicher pro Prozess (KB)) oder über die Systemvariable $ ZSTORAGE (in Kilobyte) angeben :

 set $ZSTORAGE=10000000 

Einen neuen Prozess mit den erforderlichen Speichereinstellungen gestartet? Dann ist alles einfach weiter - wir lesen und speichern.

Es gibt eine alternative (und wahrscheinlich bevorzugte) Option: Verwenden Sie die UsePPGHandler-Eigenschaft der% XML.Reader-Klasse, mit der Sie XML nicht im Speicher speichern können und die mit den Standardspeichereinstellungen arbeitet.

 set reader = ##class(%XML.Reader).%New() set reader.UsePPGHandler = 1 

mehr ... Korrelieren / Lesen usw. ...

 do reader.Next(.object) do object.%Save() 

Und so 3.722.548 mal für jede Operation :-)

Das ist anstrengend. Daher ergänzen wir unsere FIAS.AddressObject-Klasse mit einer Importmethode, die auf den gerade gezeigten Befehlen basiert:

 ClassMethod Import() { //     XML Set reader = ##class(%XML.Reader).%New() //   XML   Set status = reader.OpenURL("http://localhost/AS_ADDROBJ_20190106_90809714-fe22-45b2-929c-52bd950963e0.XML") If $$$ISERR(status) {Do $System.Status.DisplayError(status)} //       Do reader.Correlate("Object","FIAS.AddressObject") //       While (reader.Next(.object,.status)) { Set status = object.%Save() If $$$ISERR(status) {do $System.Status.DisplayError(status)} } //      ,   If $$$ISERR(status) {Do $System.Status.DisplayError(status)} } 

Lassen Sie uns die Leistung unseres Computer-Exokortex nutzen - nur ein Befehl im Terminal :

 do ##class(FIAS.AddressObject).Import() 



Ich bitte alle an den Tisch. Es gab MCD, und jetzt ist das fertige Gericht in Form eines Global mit den verifizierten Namen der russischen Städte und Gewichten fertig.



Und zum Schluss noch ein paar Worte darüber, wann 4 TB nicht ausreichen. In diesem Fall folgen wir den Streams (oder Streams, wenn Sie möchten). Die Dokumentation ist in Regalen ausgelegt. Sie können binär, Sie können symbolisch. Das Speichern im globalen Bereich ist ebenfalls nicht verboten. Das Rezept lautet: Wir nehmen einen Strom, schneiden ihn in Teile und geben ihn den Gegenständen, die wir zum Verzehr benötigen.

Darüber hinaus passten schöne adressierbare ObjectScript-Objekte und APIs in Python nicht. Es wird eine separate Geschichte geben.
Angenehm: Gartner hat gerade die jährliche Sammlung realer Benutzerbewertungen und -bewertungen in der Kategorie DBMS abgeschlossen und auf dieser Grundlage seine Bewertung des besten DBMS von 2019 veröffentlicht. Die Produkte von InterSystems Caché und InterSystems IRIS Data Platform haben die höchste Kundenauswahlbewertung erhalten. Von wem Sie gewählt haben und wie Sie bewertet haben, können Sie selbst nachsehen .
Beste Software für betriebliche Datenbankverwaltungssysteme von 2019, wie von Kunden bewertet

Source: https://habr.com/ru/post/de438062/


All Articles