MarkLogic Wilcard搜索-QConsole与Java API

MarkLogic Wilcard搜索-QConsole与Java API,java,marklogic,marklogic-9,Java,Marklogic,Marklogic 9,我相信我从基于Java的查询中看到了不同的结果,我相信在查询控制台中是等价的cts:search。这里有很多信息,我试着适当地组织它。下面是建立一个简单示例的步骤,该示例复制了我所看到的内容 使用默认设置创建新数据库 添加具有默认设置的新林 启用三字符搜索(仅限非默认数据库设置) 将下面三个json文档插入数据库 查询控制台返回doc2。Java客户端返回doc2和doc1。为什么?我希望每个人都能得到同样的结果。我想用Java获取查询控制台返回的结果。我是否用Java编写了错误的查询定义 看起

我相信我从基于Java的查询中看到了不同的结果,我相信在查询控制台中是等价的cts:search。这里有很多信息,我试着适当地组织它。下面是建立一个简单示例的步骤,该示例复制了我所看到的内容

  • 使用默认设置创建新数据库
  • 添加具有默认设置的新林
  • 启用三字符搜索(仅限非默认数据库设置)
  • 将下面三个json文档插入数据库
  • 查询控制台返回doc2。Java客户端返回doc2和doc1。为什么?我希望每个人都能得到同样的结果。我想用Java获取查询控制台返回的结果。我是否用Java编写了错误的查询定义

    看起来Java客户端通配符搜索正在搜索整个文档,尽管我已经指定只希望在给定的json属性(名称)内执行通配符搜索

    在给定客户端RawCombinedQueryDefinition的情况下,是否有方法查看或记录生成的服务器端“cts查询”?我想看看Java请求在服务器端被翻译成什么

    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"
    }
    
    用于插入文档的查询控制台代码

    xquery version "1.0-ml"; 
    xdmp:document-load("/some/path/doc1.json",
      <options xmlns="xdmp:document-load">
        <uri>/doc1.json</uri>
      </options>
    ); 
    
    Java QueryManager在易读文本中的查询

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

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

    为什么Java客户机返回city=Dayton的第一个结果


    提前谢谢

    快速查看上述代码,您的java示例中没有AND查询。因此,它是Ohio或Cincinnati的or查询。

    REST API,因此Java API默认执行未过滤的搜索(这意味着,匹配完全基于索引)。相比之下,cts:search()在默认情况下执行过滤搜索(这意味着检查结果文档以排除误报)

    如果将“未筛选”选项添加到cts:search(),它还会返回两个文档

    快速修复方法是将“过滤”选项添加到JavaAPI搜索中,但更好的大规模性能修复方法是细化索引以支持所需通配符查询的精确匹配

    元素与基于位置的通配符相关联

    因此,对于这个查询,我认为您需要打开元素单词位置和三个字符单词位置的索引配置


    希望这能有所帮助,

    感谢您的回复,大卫。我现在无法在MarkLogic文档中找到引用,但我相信“queries”数组中的任何子查询都是AND组合在一起的。在我所写的所有代码中,它们的行为都是这样的。感谢您快速且易于理解的响应。将过滤选项添加到JavaAPI显然是为了快速修复。我还保留了没有快速修复的查询,并启用了您提到的两个选项(元素单词位置和三个字符单词位置)。这也给了我我所期待的结果。我将继续使用用于索引的数据库选项,以便在完成我正在开发的JavaAPI时进行真正的微调。谢谢
    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);
            }
        }
    }
    
    {"state":"OH", "city":"Dayton", "notes":"not Cincinnati"} 
    {"state":"OH", "city":"Cincinnati", "notes":"real city"}