2016-06-06 10 views
0

Ich habe Leistungsprobleme bei der Verwendung von Wildcard-Suche nach bestimmten Buchstabenkombinationen, und ich bin mir nicht sicher, was ich sonst noch verbessern muss. Alle meine Dokumente folgen einem Umschlagmuster, das ungefähr wie folgt aussieht.schlechte Suchleistung für bestimmte Platzhalterabfragen

<pdbe:person-envelope> 
    <person xmlns="http://schemas.abbvienet.com/people-db/model"> 
     <account> 
      <domain/> 
      <username/> 
     </account> 
     <upi/> 
     <title/> 
     <firstName> 
      <preferred/> 
      <given/> 
     </firstName> 
     <middleName/> 
     <lastName> 
      <preferred/> 
      <given/> 
     </lastName> 
    </person> 
    <pdbe:raw/> 
</pdbe:person-envelope> 

Ich habe ein Feld namens Name definiert, die den Vor- und den Nachnamen Pfade umfasst:

{ 
    "field-name": "name", 
    "field-path": [ 
    { 
     "path": "/pdbe:person-envelope/pdbm:person/pdbm:firstName", 
     "weight": 1 
    }, 
    { 
     "path": "/pdbe:person-envelope/pdbm:person/pdbm:lastName", 
     "weight": 1 
    } 
    ], 
    "trailing-wildcard-searches": true, 
    "trailing-wildcard-word-positions": true, 
    "three-character-searches": true 
} 

Wenn ich einige Abfragen tun mit Suche: Suche, einige kommen schnell zurück, während andere wieder langsam . Dies ist mit den gefilterten Abfragen.

search:search("name:ha*", 
    <options xmlns="http://marklogic.com/appservices/search"> 
    <constraint name="name"> 
     <word> 
     <field name="name"/> 
     </word> 
    </constraint> 
    <return-plan>true</return-plan> 
    </options> 
) 

Ich kann aus dem Abfrageplan sehen, dass es über alle 136547 Fragmente in der DB filtern wird. Aber diese Abfrage funktioniert schnell.

<search:query-resolution-time>PT0.013205S</search:query-resolution-time> 
<search:snippet-resolution-time>PT0.008933S</search:snippet-resolution-time> 
<search:total-time>PT0.036542S</search:total-time> 

jedoch eine Suche nach name:tj* dauert eine lange Zeit, und filtert auch alle der 136.547 Fragmente über.

<search:query-resolution-time>PT6.168373S</search:query-resolution-time> 
<search:snippet-resolution-time>PT0.004935S</search:snippet-resolution-time> 
<search:total-time>PT12.327275S</search:total-time> 

Ich habe die gleichen Indizes für beide. Gibt es weitere Indizes, die ich aktivieren sollte, wenn ich gerade eine Suche über die Feldbeschränkung durchführe? Ich habe diese anderen Indizes im Allgemeinen in der Datenbank selbst aktiviert.

"collection-lexicon": true, 
    "triple-index": true, 
    "word-searches": true, 
    "word-positions": true 

Ich habe versucht, eine ungefilterte Abfrage zu tun, aber das half nicht, wie ich ein paar Streichhölzer auf das gesamte Dokument bekam, und nicht auf die Felder wollte ich. Ich habe sogar versucht, das Wurzelfragment nur auf mein persönliches Element zu setzen, aber das schien den Dingen nicht zu helfen.

"fragment-root": [ 
    { 
     "namespace-uri": "http://schemas.abbvienet.com/people-db/model", 
     "localname": "person" 
    } 
    ] 

Danke für irgendwelche Ideen.

Antwort

3

Fragmentstämme sind hilfreich, wenn Sie einen suchbaren Ausdruck für dieses Personenelement verwenden möchten, und meistens, wenn es mehrmals in einem Dokument vorkommt. Dadurch wird Ihre aktuelle Suche nicht auf dieses Element beschränkt.

In Ihrem Fall haben Sie eine Reihe von relevanten Optionen aktiviert, aber die Platzhalteroption funktioniert nur für 4 Zeichen oder mehr. Wenn Sie nach Platzhaltern mit weniger Zeichen suchen möchten, müssen Sie die Suchoptionen für drei, zwei und ein Zeichen aktivieren.

Die oben genannten Suchbegriffe enthielten jeweils zwei Zeichen mit einem Platzhalter. Da Sie nur die Option mit drei Zeichen aktiviert haben, musste sie sich auf die Filterung verlassen. Die Tatsache, dass einige schnell laufen, manche langsam, liegt wahrscheinlich am Caching. Wenn Sie dieselbe Abfrage wiederholen, gibt MarkLogic das Ergebnis aus dem Cache zurück.

Für Leistungstests müssen Sie MarkLogic entweder regelmäßig neu starten, um Caches zu leeren, oder nach (halb-) zufälligen Strings suchen, um zu verhindern, dass MarkLogic zwischenspeichern kann. Oder vielleicht beides ..

HTH!

+0

Zusätzlich zu dem, was Geert gesagt hat, gibt es auch Fälle, in denen Sie statt der 2 und 3 Char-Wildcard-Optionen die Einstellungen Are-Is beibehalten und ein Wortlexikon auf das fragliche Element/Feld einfügen können. Dann machen Sie Ihre Ausdruckserweiterung im Wesentlichen basierend auf Element-Wort-Übereinstimmung. Auch hier kommt es auf Ihren endgültigen Anwendungsfall an.Sie können diesen Ansatz als benutzerdefinierte Einschränkung einbinden. Dies kann sogar mit Dingen wie der eifrigen Option auf cts: field-word-match abgestimmt werden und auch direkt durch jede Gesamtstruktur gehen. Was ist effizienter/schneller? Sie müssen testen und tunen. –

+0

Danke für die Kommentare. Ich verwende das tatsächlich als benutzerdefinierte Einschränkung. In den Suchoptionen (für Autovervollständigung) überschreibe ich die Begriffsbehandlung, um diese spezifischen Felder zu durchsuchen. Dies ist eine automatische Vervollständigung, um schnell die richtige Person zu finden, wenn der Benutzer tippt .. dies könnte nach Vor-/Nachname, Benutzername oder interner Kennung geschehen. Aus irgendeinem Grund dachte ich, ich würde irgendwo lesen, dass das Aktivieren der Drei-Zeichen-Suche auch die zwei- und ein-Zeichen-Fälle behandeln würde, aber ich hätte das vielleicht falsch verstanden. Durch Aktivieren dieser Indizes wurde das Problem behoben. –

+0

Ich sehe, wo ich es jetzt falsch gelesen habe. Die Dokumentation sagt "Dieser Index wird nicht benötigt, wenn Sie drei Zeichen suchen und ein Wortlexikon haben." Wie @DavidEnnis erwähnt, könnte ich das Wort Lexikon hinzufügen, was ich nicht tat. –