2017-12-29 24 views
2

Java 기반 쿼리와 다른 결과를보고 있으며 쿼리 콘솔에서 동일한 cts : search로 생각합니다. 여기에 많은 정보가 있으며 적절하게 정리하려고했습니다. 여기 내가 보는 것을 복제하는 간단한 예제를 설정하는 단계가 있습니다.MarkLogic Wilcard Search - QConsole vs. Java API

  1. 세 문자 검색 (전용이 아닌 기본 데이터베이스 설정) 사용
  2. 기본 설정으로 새 포리스트 추가 기본 설정으로 새 데이터베이스를 만듭니다
  3. 삽입 데이터베이스에 아래의 세 가지 JSON 문서

쿼리 콘솔은 doc2를 반환합니다. Java 클라이언트는 doc2 및 doc1을 반환합니다. 왜? 나는 각각으로부터 동일한 결과를 기대할 것이다. 쿼리 콘솔이 반환하는 결과를 Java에서 얻고 싶습니다. Java에서 쿼리 정의를 잘못 작성하고 있습니까? 그것은 자바 클라이언트 와일드 카드 검색과 같은

내가 단지 주어진 JSON 재산권의 내부 와일드 카드 검색을 수행하도록 지정한 경우에도 전체 문서를 검색한다 (이름입니다.)

거기인가 클라이언트 쪽 RawCombinedQueryDefinition이 주어진 결과 서버 측 "cts 쿼리"를 보거나 로그하는 방법은 무엇입니까? Java 요청이 서버 측에서 변환되는 것을보고 싶습니다.

문서

xquery version "1.0-ml"; 
xdmp:document-load("/some/path/doc1.json", 
    <options xmlns="xdmp:document-load"> 
    <uri>/doc1.json</uri> 
    </options> 
); 
0123을 삽입하는 데 사용 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" 
} 

쿼리 콘솔 코드

쿼리 콘솔 코드는 텍스트를

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

자바 코드

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()

결과를 읽기 쉬운

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*") 
)) 
) 

자바 QueryManager 쿼리를 검색하는 데 사용

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

Java 클라이언트가 city = Dayton 인 경우 첫 번째 결과를 반환하는 이유는 무엇입니까?

미리 감사드립니다.

답변

3

REST API 및 따라서 Java API는 기본적으로 필터링되지 않은 검색을 실행합니다. 즉, 일치는 인덱스에 전적으로 기초합니다. 대조적으로, cts : search()는 기본적으로 필터링 된 검색을 실행합니다 (결과 문서가 false positive를 제거하도록 검사 됨).

"필터되지 않음"옵션을 cts : search()에 추가하면 두 문서도 모두 반환됩니다.

빠른 수정은 Java API 검색에 "filtered"옵션을 추가하는 것이지만, 성능을 향상시키기위한 더 나은 수정은 필요한 와일드 카드 쿼리에 대한 정확한 일치를 지원하도록 인덱스를 수정하는 것입니다.

요소는 위치에 따라 와일드 카드와 상관됩니다.

따라서이 쿼리에서 요소 단어 위치와 3 자 단어 위치에 대한 인덱스 구성을 설정해야한다고 생각합니다.

도와 드리겠습니다.

+0

빠르고 쉽게 답변 해 주셔서 감사합니다. Java API에 필터링 된 옵션을 추가하면 빠른 수정이 가능합니다. 또한 빠른 수정없이 쿼리를 남겨두고 언급 한 두 가지 옵션 (요소 단어 위치와 세 문자 단어 위치)을 켰습니다. 그것은 또한 제가 기대했던 결과를 돌려주었습니다. 내가 작업중인 Java API를 완성 할 때 인덱싱을위한 데이터베이스 옵션을 계속 사용하여 미세 조정을 할 것입니다. 감사! –

0

위 코드를 간략하게 살펴보면 Java 예에서는 AND 쿼리가 없습니다. 따라서 오하이오 또는 신시네티에 대한 또는 쿼리입니다.

+0

David 님의 답변에 감사드립니다. 나는 현재 MarkLogic 문서에서 참조를 찾을 수는 없지만 "쿼리"배열의 하위 쿼리는 모두 함께 처리됩니다. 필자가 작성한 모든 코드에서 그들은 분명히 그런 식으로 행동했습니다. –