Skip to content

Commit 4d40a46

Browse files
rahulvudutalaMarkLogic Builder
authored andcommitted
DHFPROD-3581: Search within a specific facet of string datatype
1 parent 4a79b8c commit 4d40a46

File tree

8 files changed

+223
-0
lines changed

8 files changed

+223
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"functionName": "getFacetValues",
3+
"params": [
4+
{
5+
"name": "entityName",
6+
"datatype": "string"
7+
},
8+
{
9+
"name": "facetName",
10+
"datatype": "string"
11+
},
12+
{
13+
"name": "indexType",
14+
"datatype": "string"
15+
},
16+
{
17+
"name": "searchStr",
18+
"datatype": "string"
19+
},
20+
{
21+
"name": "limit",
22+
"datatype": "int"
23+
}
24+
],
25+
"return": {
26+
"datatype": "jsonDocument",
27+
"$javaClass": "com.fasterxml.jackson.databind.JsonNode"
28+
}
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
var entityName;
4+
var facetName;
5+
var indexType;
6+
var searchStr;
7+
var limit;
8+
9+
var query;
10+
11+
if(indexType === 'elementRangeIndex') {
12+
query = cts.elementReference(facetName);
13+
} else if(indexType === 'fieldRangeIndex') {
14+
query = cts.fieldReference(facetName);
15+
} else if(indexType === 'collection') {
16+
query = cts.collectionReference();
17+
} else {
18+
query = cts.pathReference("//*:instance/" + entityName + "/" + facetName);
19+
}
20+
21+
var facetValues = cts.valueMatch(query, searchStr + "*",
22+
["item-order", "ascending", "limit=" + limit]).toArray().map(String);
23+
24+
if (facetValues.length < limit) {
25+
var moreFacetValues = cts.valueMatch(query, "?*" + searchStr + "*",
26+
["item-order", "ascending", "limit=" + limit]).toArray().map(String);
27+
facetValues = Array.from(
28+
[...new Set([...facetValues, ...moreFacetValues])]).slice(0, limit);
29+
}
30+
31+
facetValues;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"endpointDirectory": "/data-hub/5/data-services/searchFacetValues/",
3+
"$javaClass": "com.marklogic.hub.dataservices.FacetValuesSearch"
4+
}

marklogic-data-hub/src/test/java/com/marklogic/bootstrap/Installer.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package com.marklogic.bootstrap;
22

33

4+
import java.io.IOException;
5+
import java.nio.file.Path;
6+
import java.nio.file.Paths;
7+
48
import com.marklogic.hub.ApplicationConfig;
59
import com.marklogic.hub.HubTestBase;
610
import com.marklogic.mgmt.api.API;
711
import com.marklogic.mgmt.api.security.User;
12+
13+
import org.apache.commons.io.FileUtils;
814
import org.slf4j.Logger;
915
import org.slf4j.LoggerFactory;
1016
import org.springframework.boot.SpringApplication;
@@ -40,6 +46,14 @@ public void bootstrapHub() {
4046
}
4147

4248
if (!isInstalled) {
49+
try {
50+
Path srcDir = Paths.get("src", "test", "ml-config", "databases","final-database.json");
51+
Path dstDir = Paths.get(adminHubConfig.getUserDatabaseDir().toString(), "test-final-database.json");
52+
FileUtils.copyFile(srcDir.toAbsolutePath().toFile(), dstDir.toAbsolutePath().toFile());
53+
} catch (IOException ioe) {
54+
ioe.printStackTrace();
55+
}
56+
4357
dataHub.install();
4458

4559
User dataHubDeveloper = new User(new API(adminHubConfig.getManageClient()), "test-data-hub-developer");

marklogic-data-hub/src/test/ml-config/databases/final-database.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@
1818
"collation" : "http://marklogic.com/collation//S1",
1919
"range-value-positions" : false,
2020
"invalid-values" : "reject"
21+
},
22+
{
23+
"scalar-type" : "string",
24+
"namespace-uri" : "",
25+
"localname" : "searchStrCityFacet",
26+
"collation" : "http://marklogic.com/collation/",
27+
"range-value-positions" : false,
28+
"invalid-values" : "reject"
29+
}
30+
],
31+
"range-path-index": [
32+
{
33+
"scalar-type": "string",
34+
"path-expression": "//*:instance/SearchFacetsEntity/searchStrNameFacet",
35+
"collation": "http://marklogic.com/collation/",
36+
"range-value-positions": false,
37+
"invalid-values": "reject"
2138
}
2239
]
2340
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const test = require("/test/test-helper.xqy");
2+
3+
function invokeService(entityName, facetName, indexType, searchStr, limit) {
4+
return fn.head(xdmp.invoke(
5+
"/data-hub/5/data-services/searchFacetValues/searchFacetValues.sjs",
6+
{
7+
"entityName": entityName,
8+
"facetName": facetName,
9+
"indexType": indexType,
10+
"searchStr": searchStr,
11+
"limit": limit
12+
}
13+
));
14+
}
15+
16+
function testSearchOnRangePathIndexes() {
17+
const result = invokeService("SearchFacetsEntity", "searchStrNameFacet",
18+
"rangeIndex", "name", 10);
19+
return [
20+
test.assertEqual(3, result.length),
21+
test.assertTrue(result.includes("firstName1")),
22+
test.assertTrue(result.includes("firstName2")),
23+
test.assertTrue(result.includes("firstName3"))
24+
];
25+
}
26+
27+
function testSearchOnRangeElementIndexes() {
28+
const result = invokeService("", "searchStrCityFacet", "elementRangeIndex",
29+
"ra", 10);
30+
return [
31+
test.assertEqual(2, result.length),
32+
test.assertTrue(result.includes("ranchi")),
33+
test.assertTrue(result.includes("Raleigh"))
34+
];
35+
}
36+
37+
function testSearchOnRangeFieldIndexes() {
38+
const result = invokeService("", "datahubCreatedInFlow", "fieldRangeIndex",
39+
"flow", 10);
40+
return [
41+
test.assertEqual(3, result.length),
42+
test.assertTrue(result.includes("my-flow-1")),
43+
test.assertTrue(result.includes("my-flow-2")),
44+
test.assertTrue(result.includes("my-flow-3"))
45+
];
46+
}
47+
48+
function testSearchOnCollectionNames() {
49+
const result = invokeService("", "", "collection", "doc", 10);
50+
return [
51+
test.assertEqual(3, result.length),
52+
test.assertTrue(result.includes("doc1")),
53+
test.assertTrue(result.includes("doc2")),
54+
test.assertTrue(result.includes("doc3"))
55+
];
56+
}
57+
58+
[]
59+
.concat(testSearchOnRangePathIndexes())
60+
.concat(testSearchOnRangeElementIndexes())
61+
.concat(testSearchOnRangeFieldIndexes())
62+
.concat(testSearchOnCollectionNames());
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
declareUpdate();
2+
3+
xdmp.documentInsert("/exp/doc1",
4+
{
5+
"envelope": {
6+
"instance": {
7+
"SearchFacetsEntity": {
8+
"searchStrNameFacet": "firstName1",
9+
"searchStrCityFacet": "Reims"
10+
}
11+
}
12+
}
13+
},
14+
{
15+
permissions: xdmp.defaultPermissions(),
16+
collections: "doc1",
17+
metadata: {
18+
"datahubCreatedInFlow": "my-flow-1",
19+
"datahubCreatedByStep": "my-step-1"
20+
}
21+
});
22+
23+
xdmp.documentInsert("/exp/doc2",
24+
{
25+
"envelope": {
26+
"instance": {
27+
"SearchFacetsEntity": {
28+
"searchStrNameFacet": "firstName2",
29+
"searchStrCityFacet": "Raleigh"
30+
}
31+
}
32+
}
33+
},
34+
{
35+
permissions: xdmp.defaultPermissions(),
36+
collections: "doc2",
37+
metadata: {
38+
"datahubCreatedInFlow": "my-flow-2",
39+
"datahubCreatedByStep": "my-step-2"
40+
}
41+
});
42+
43+
xdmp.documentInsert("/exp/doc3",
44+
{
45+
"envelope": {
46+
"instance": {
47+
"SearchFacetsEntity": {
48+
"searchStrNameFacet": "firstName3",
49+
"searchStrCityFacet": "ranchi"
50+
}
51+
}
52+
}
53+
},
54+
{
55+
permissions: xdmp.defaultPermissions(),
56+
collections: "doc3",
57+
metadata: {
58+
"datahubCreatedInFlow": "my-flow-3",
59+
"datahubCreatedByStep": "my-step-3"
60+
}
61+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declareUpdate();
2+
3+
xdmp.collectionDelete("doc1");
4+
xdmp.collectionDelete("doc2");
5+
xdmp.collectionDelete("doc3");

0 commit comments

Comments
 (0)