2017-02-20 2 views
1

Wir erstellen eine Unternehmensanwendung mit ML als Back-End. Viele Bildschirme in der Anwendung haben Dropdown-Menüs, die unterschiedliche Werte von Elementen in Dokumenten erfordern. Daher haben wir einen Elementbereichsindex für diese Elemente erstellt und den Code bereit gestellt, um die verschiedenen Werte mithilfe des Bereichsindex abzurufen.Einschränkungsindex für Elemente in Dokumenten in einer bestimmten Sammlung

Jetzt trennen wir Dokumente logisch in verschiedene Sammlungen - wie "basedata" Sammlung, die alle Anwendungsbasisdaten Dokumente und "transactiondata" Ansammlung hält, die alle eingehenden/ausgehenden Transaktionen zu unserer Anwendung hält.

Jetzt gilt es, den Bereichsindex auf die Basisdatensammeldokumente und nicht auf die Transaktionsdatendokumente zu beschränken.

Zum Beispiel: Wenn wir ein Element Entfernungs-Index für lokalerName = „entityName“ haben wir für die entityName Werte in Dokumenten in Transaktionsdatensammlung nicht wollen der Bereich Index gebaut werden. Wir möchten, dass die eindeutigen Werte von "entityName" nur in Dokumenten vorkommen, die an basedata collection angehängt sind.

Wie können wir das erreichen?

Edit:

Dank David und grtjn.

Dies ist, was wir derzeit in der Java-Schicht tun: Der Code unten richtig kehrt die unterschiedlichen Namen für das Feld entityName, die eine Reihe Index erstellt hat.

String valueOptionString = 
    " <search:options xmlns:search="http://marklogic.com/appservices/search"> 
     <search:values name="entityName"> 
      <search:range type="xs:string"> 
       <search:element name="entityName"> 
       </search:element> 
      </search:range> 
     </search:values> 
    </search:options> ";  

QueryManager queryMgr = client.newQueryManager(); 
    QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager(); 
    optionsMgr.writeOptions("DistinctValues", new StringHandle(valueOptionString)); 

    ValuesDefinition vdef = queryMgr.newValuesDefinition("entityName", "DistinctValues"); 
    ValuesHandle vh = queryMgr.values(vdef, new ValuesHandle()); 

    for (CountedDistinctValue value : vh.getValues()) { 
     System.out.println("Distinct value is :: " + 
      value.get("xs:string", String.class)); 
    } 

Wie Sie sehen, ich bin nicht die Sammlung irgendwo auf dem queryMgr.values ​​Einstellung(); Basierend auf dem Vorschlag vorgesehen, habe ich versucht, die Sammlung Einschränkung int die valueOptionString hinzufügen, aber es funktioniert nicht. Ist das der richtige Ansatz? Gibt es eine andere Art und Weise aus

<search:options xmlns:search="http://marklogic.com/appservices/search"> 
<search:values name="createdBy"> 
    <search:range type="xs:string"> 
     <search:element name="createdBy"/> 
    </search:range> 
    <search:collection> 
     <search:uri>basedaata</search:uri> 
     <search:uri>tansactiondata</search:uri> 
    </search:collection> 
</search:values> 
</search:options> 

Fehler aufgetreten:

Local message: /config/query write failed: Bad Request. Server Message: RESTAPI-INVALIDCONTENT: (err:FOER0000) Invalid content: Op 
eration results in invalid Options: XDMP-VALIDATEUNEXPECTED: (err:XQDY0027) validate strict { $opt } -- Invalid node: Found text{"basedaata..."} but expected() at fn:doc("") 

EDIT 2:

Basierend auf den unten Antworten, die ich meinen Code aktualisiert haben, um „Zusatz- Abfrage "Abschnitt in der optionalen Abfrage, um die verschiedenen zurückgegebenen Werte zu enthalten. Allerdings sieht es die zusätzliche Abfrage Teil werden ignoriert und nicht funktioniert als

Aktualisiert optionale Abfrage erwartet:

<search:options xmlns:search="http://marklogic.com/appservices/search"> 
    <search:values name="entityName"> 
     <search:range type="xs:string"> 
      <search:element name="entityName"/> 
     </search:range> 
    </search:values> 
    <search:additional-query> 
     <cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
      <cts:uri>basedata</cts:uri> 
      <cts:uri>DistinctValueTest</cts:uri> 
     </cts:collection-query> 
    </search:additional-query> 
</search:options> 

Im Folgenden sind die Dokumente ich habe. Auch ich habe Element Bereich Index für Feld entityName.

Dokument in basedata Sammlung:

<?xml version="1.0" encoding="UTF-8"?> 
<entity> 
    <entityName>Company</entityName> 
    <createdBy>CompanyOwner</createdBy> 
    <createdDate>2017-01-01T05:56:35.360Z</createdDate> 
    <status>Active</status> 
    <entityattributes> 
     <entityattribute> 
     </entityattribute> 
    </entityattributes> 
</entity> 

erstellt nun eine Testsammlung namens DistinctValueTest und hinzugefügt in dieser Sammlung ein Dokument zu Testzwecken.

Dokument in DistinctValueTest Sammlung:

<?xml version="1.0" encoding="UTF-8"?> 
<entity> 
    <entityName>DistinctValueTestEntity</entityName> 
    <createdBy>DistinctValuteSystemNew</createdBy> 
    <createdDate>2017-01-03T05:56:35.360Z</createdDate> 
    <status>Active</status> 
    <entityattributes> 
     <entityattribute> 
     </entityattribute> 
    </entityattributes> 
</entity> 

Die Ausgabe des Programms ist: Unternehmen, DistinctValueteSystemNew wenn beide Sammlungen in dem zusätzlichen Abfrage Abschnitt

<cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
    <cts:uri>basedata</cts:uri> 
    <cts:uri>DistinctValueTest</cts:uri> 
</cts:collection-query 

jedoch geliefert werden, wenn i nur bieten "basedata" Sammlung in der cts: uri es zeigt immer noch die Ausgabe als Firma, DistinctValueteSystemNew, anstatt nur Unternehmen

+0

Es könnte besser gewesen sein, den Bearbeitungsteil in eine separate Frage zu stellen. – grtjn

Antwort

3

Statt mehrere Indizes für jede Kombination von Kriterien zu erstellen, kombinieren Sie Indizes beim Lesen. Die cts:values-Funktion nimmt einen vierten Parameter, der eine Abfrage darstellt, die die Fragmente, von denen Werte abgeleitet werden, abschneidet. In Ihrem Fall wäre es etwa so aussehen:

cts:values(
    cts:element-reference(xs:QName("entityName")), 
(), 
(), 
    cts:collection-query("basedata") 
) 

ähnliche Effekte lassen sich mit der etwas abstraktere search:values Funktion und die /v1/values REST-Endpunkte erreicht werden.

HTH!

+0

Danke David/grtjn. Ich habe das obige versucht und meine Frage mit dem Problem aktualisiert, dem ich begegnet bin. Lass es mich wissen, bitte. Danke im Voraus. – nocoder

1

Aufbauend auf GRTJN's Antwort und Ihre aktualisierte Frage, eine einfache Möglichkeit, die Werte, die Sie zurück zu einer bestimmten Sammlung zu beschränken ist mit einem additional-query zu Ihren Optionen hinzugefügt.

<search:options xmlns:search="http://marklogic.com/appservices/search"> 
    <search:values name="createdBy"> 
    <search:range type="xs:string"> 
     <search:element name="createdBy"/> 
    </search:range> 
    </search:values> 
    <search:additional-query> 
    <cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
     <cts:uri>basedata</cts:uri> 
     <cts:uri>transactiondata</cts:uri> 
    </cts:collection-query> 
    </search:additional-query> 
</search:options> 

Ein additional-query wird jedem mit diesem Satz von Optionen ausführen Abfrage hinzugefügt.

+0

Zusätzliche Abfrage ist eine Möglichkeit, damit zu arbeiten, aber Ihr Java-Code wird einen Aufruf an "/ v1/values ​​/ createdBy" unter den Abdeckungen tätigen. Dieser REST-Endpunkt akzeptiert einen 'sammlung'-Anforderungs-Parameter, einen 'q'-Parameter und einen' strukturierterAbfrage-Parameter ', die alle dazu verwendet werden können, den gleichen Effekt wie die zusätzliche Abfrage zu erhalten, jedoch auf eine dynamischere Weise. Es sollte Möglichkeiten geben, dem 'queryMgr'-Objekt mitzuteilen, dass es zusätzliche Einschränkungen durchläuft. (Jeder in der Umgebung könnte wissen, wie?) – grtjn

+0

@grtjn mit funktioniert nicht wie erwartet. Meine ursprüngliche Frage wurde aktualisiert. Bitte überprüfen Sie Edit 2. – nocoder

+0

@Dave jedes Update auf das Problem, das ich in der Edit 2 meiner Frage oben bin? Danke für Ihre Hilfe. – nocoder

Verwandte Themen