2017-12-29 6 views
2

Ich glaube, ich sehe verschiedene Ergebnisse von einer Java-basierten Abfrage und was ich glaube, ist die äquivalente cts: Suche in der Abfrage-Konsole. Es gibt viele Informationen hier und ich habe versucht, es angemessen zu organisieren. Hier sind die Schritte zum Einrichten eines einfachen Beispiels, das repliziert, was ich sehe.MarkLogic Wilcard Suche - QConsole vs. Java API

  1. Neue Datenbank erstellen mit den Standardeinstellungen
  2. neuen Gesamtstruktur hinzufügen mit den Standardeinstellungen
  3. Aktivieren drei Zeichen sucht (nur Nicht-Standard-Datenbank-Einstellung)
  4. Legen Sie die drei json Dokumente unten in die Datenbank

Die Abfragekonsole gibt doc2 zurück. Der Java-Client gibt doc2 UND doc1 zurück. Warum? Ich würde von jedem die gleichen Ergebnisse erwarten. Ich möchte die Ergebnisse in Java erhalten, die die Abfragekonsole zurückgibt. Schreib ich die Abfragedefinition in Java falsch?

Es sieht aus wie die Java-Client Wildcard-Suche wird das gesamte Dokument suchen, obwohl ich angegeben habe, dass ich nur eine Wildcard-Suche innerhalb der gegebenen json-Eigenschaft tun will (Namen.)

Gibt es ein Möglichkeit, die resultierende serverseitige "cts-Abfrage" bei einer clientseitigen RawCombinedQueryDefinition zu sehen oder zu protokollieren? Ich würde gerne sehen, worauf die Java-Anfrage auf der Serverseite übersetzt wird.

doc1.json

{ 
    "state": "OH", 
    "city": "Dayton", 
    "notes": "not Cincinnati" 
} 

doc2.json

{ 
    "state": "OH", 
    "city": "Cincinnati", 
    "notes": "real city" 
} 

doc3.json

{ 
    "state": "OH", 
    "city": "Daytona", 
    "notes": "this is a made up city" 
} 

Abfrage Konsole Code verwendet, um Dokumente einzufügen

xquery version "1.0-ml"; 
xdmp:document-load("/some/path/doc1.json", 
    <options xmlns="xdmp:document-load"> 
    <uri>/doc1.json</uri> 
    </options> 
); 

Abfrage Konsole Code

xquery version "1.0-ml"; 
cts:search(fn:collection(), 
    cts:and-query((
    cts:json-property-value-query("state", "OH"), 
    cts:json-property-value-query("city", "*Cincinnati*") 
)) 
) 

Java QueryManager Abfrage in leicht zu lesbarer Text

{ 
    "search": { 
    "query": { 
     "queries": [ 
     { 
      "value-query": { 
      "type": "string", 
      "json-property": "state", 
      "text": "OH" 
      } 
     }, 
     { 
      "value-query": { 
      "type": "string", 
      "json-property": "city", 
      "text": "*Cincinnati*" 
      } 
     } 
     ] 
    } 
    } 
} 

Java-Code

import com.marklogic.client.DatabaseClient; 
import com.marklogic.client.DatabaseClientFactory; 
import com.marklogic.client.document.DocumentPage; 
import com.marklogic.client.document.DocumentRecord; 
import com.marklogic.client.document.JSONDocumentManager; 
import com.marklogic.client.io.Format; 
import com.marklogic.client.io.StringHandle; 
import com.marklogic.client.query.QueryManager; 
import com.marklogic.client.query.RawCombinedQueryDefinition; 
import org.junit.Test; 

public class MarkLogicTest 
{ 
    @Test 
    public void testWildcardSearch() 
    { 
     DatabaseClientFactory.SecurityContext securityContext = new DatabaseClientFactory.DigestAuthContext("admin", "admin"); 
     DatabaseClient client = DatabaseClientFactory.newClient("localhost", 8000, "test", securityContext); 
     QueryManager queryManager = client.newQueryManager(); 
     JSONDocumentManager documentManager = client.newJSONDocumentManager(); 

     String query = "{\n" + 
       " \"search\": {\n" + 
       " \"query\": {\n" + 
       "  \"queries\": [\n" + 
       "  {\n" + 
       "   \"value-query\": {\n" + 
       "   \"type\": \"string\",\n" + 
       "   \"json-property\": \"state\",\n" + 
       "   \"text\": \"OH\"\n" + 
       "   }\n" + 
       "  },\n" + 
       "  {\n" + 
       "   \"value-query\": {\n" + 
       "   \"type\": \"string\",\n" + 
       "   \"json-property\": \"city\",\n" + 
       "   \"text\": \"*Cincinnati*\"\n" + 
       "   }\n" + 
       "  }\n" + 
       "  ]\n" + 
       " }\n" + 
       " }\n" + 
       "}"; 

     StringHandle queryHandle = new StringHandle(query).withFormat(Format.JSON); 
     RawCombinedQueryDefinition queryDef = queryManager.newRawCombinedQueryDefinition(queryHandle); 
     DocumentPage documents = documentManager.search(queryDef, 1); 

     while (documents.hasNext()) 
     { 
      DocumentRecord document = documents.next(); 
      StringHandle resultHandle = document.getContent(new StringHandle()); 
      String result = resultHandle.get(); 
      System.out.println(result); 
     } 
    } 
} 

System.out.println() führt

zur Suche verwendet
{"state":"OH", "city":"Dayton", "notes":"not Cincinnati"} 
{"state":"OH", "city":"Cincinnati", "notes":"real city"} 

Warum gibt der Java-Client das erste Ergebnis zurück, wo city = Dayton?

Vielen Dank im Voraus!

Antwort

3

Die REST-API und somit die Java-API führt standardmäßig eine ungefilterte Suche durch (dh die Übereinstimmungen basieren ausschließlich auf den Indizes). Im Gegensatz dazu führt cts: search() standardmäßig eine gefilterte Suche durch (dh, die Ergebnisdokumente werden überprüft, um falsche Positive auszuschließen).

Wenn Sie die Option "ungefiltert" zu cts: search() hinzufügen, werden auch beide Dokumente zurückgegeben. Die schnelle Lösung besteht darin, die Java-API-Suche um die Option "filtered" zu erweitern. Die bessere Lösung für die Leistung bei Skalierung besteht jedoch darin, die Indizes so zu verfeinern, dass die exakte Übereinstimmung für die erforderlichen Platzhalteranfragen unterstützt wird.

Elemente werden basierend auf der Position mit Platzhaltern korreliert.

Daher glaube ich, dass Sie für diese Abfrage die Indexkonfigurationen für Elementwortpositionen und für drei Zeichenwortpositionen aktivieren müssen.

In der Hoffnung, dass hilft,

+0

Vielen Dank für die schnelle und verständliche Antwort. Das Hinzufügen der gefilterten Option zur Java API wurde definitiv für eine schnelle Lösung vorgenommen. Ich habe auch die Abfrage ohne die Schnellkorrektur verlassen und die beiden Optionen, die Sie erwähnt haben, aktiviert (Elementwortpositionen und drei Zeichenwortpositionen). Das gab mir auch die Ergebnisse zurück, die ich erwartet hatte. Ich werde weiterhin mit den Datenbankoptionen für die Indexierung spielen, um eine Feinabstimmung vorzunehmen, wenn ich die Java-API fertigstelle, an der ich gerade arbeite. Vielen Dank! –

0

Von einem kurzen Blick auf den obigen Code haben Sie nicht die AND-Abfrage in Ihrem Java-Beispiel. Daher ist es eine or-Abfrage für Ohio oder Cincinnati.

+0

Vielen Dank für Ihre Antwort David. Ich kann nicht für das Leben von mir die Referenz in der MarkLogic-Dokumentation jetzt finden, aber ich glaube, dass alle Unterabfragen im Array "Abfragen" zusammengefügt sind. In all dem Code, den ich geschrieben habe, haben sie sich sicherlich so verhalten. –

Verwandte Themen