У меня проблема с неправильными результатами при отправке запроса с подстановочными знаками в моем проекте Java. В моей базе данных Marklogic я сохранил несколько файлов json с одинаковой структурой. Я хочу получить те jsons, которые в поле с именем «icsList» (это список строк) начинаются с заданной строки.
Пример icsList в json выглядит так:
Результаты моего примера:
Запрос - Строка "50" Результат - все jsons (даже те, у которых нет "50" в их icsList)
Запрос — строка «50». Результат - Jsons, у которых есть «50». внутри icsList (например: «50.010.10», «50.010.20», а также «12.50.60»)
Как я уже упоминал ранее, моя основная цель - получить все jsons, которые в поле с именем "icsList" НАЧИНАЮТСЯ с заданной строкой. Моя вторая цель - избавиться от необходимой точки в конце строки запроса.
Мой код:
StructuredQueryBuilder sqb = new StructuredQueryBuilder();
String[] wordOptions = {"wildcarded"};
StructuredQueryDefinition queryDefinitionIcs = sqb.word(sqb.jsonProperty("icsList"),
null, wordOptions, 1, searchText + "*");
StructuredQueryDefinition query = sqb.and(queryDefinitionIcs);
query.setCollections(DocumentCollection.ATTRIBUTES.getName());
try (DocumentPage search = jsonDocumentManager.search(query, 1L)) {
JacksonHandle handle = new JacksonHandle();
List<DocumentAttributes> documentAttributes = StreamSupport.stream(search.spliterator(), false)
.map(v -> mapToDocumentAttributes(handle, v))
.toList();
}
private DocumentAttributes mapToDocumentAttributes(JacksonHandle handle, DocumentRecord v) {
try {
var doc = objectMapper.treeToValue(v.getContent(handle).get(), DocumentAttributes.class);
return doc;
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
В pom.xml у меня есть:
<dependency>
<groupId>com.marklogic</groupId>
<artifactId>marklogic-client-api</artifactId>
<version>5.5.3</version>
</dependency>
Если вы включите двухсимвольный поиск в базе данных, вы можете искать «50*» вместо «50.*», но это может существенно повлиять на размер ваших индексов и производительность приема, поэтому это может быть нежелательно.
Возможно, вам потребуется включить поиск по трем символам или поиск с подстановочными знаками в конце базы данных, чтобы иметь возможность эффективно искать с такими короткими значениями с подстановочными знаками, как "50.*"
или "50.* *"
.
https://docs.marklogic.com/guide/search-dev/wildcard#id_39731
Если вы использовали value() для создания cts:json-property-value-query()
вместо словесного запроса и включили .
в значение с подстановочными знаками, то он найдет только тот последний документ, который начинается с 50.
.
Например, этот поиск:
cts:search(doc(), cts:json-property-value-query("icsList", "50.*"))
или:
cts:search(doc(), cts:json-property-value-query("icsList", "50* *"))
Обратите внимание, что текстовое содержимое значения в
cts:json-property-value-query
обрабатывается так же, как фраза вcts:word-query
, где фраза является значением свойства. Таким образом, любые подстановочные знаки и/или правила формирования корней рассматриваются как фраза. Например, если у вас есть значение свойства"hello friend"
с включенным подстановочным знаком для запроса,cts:json-property-value-query
для"he*"
не будет соответствовать, поскольку совпадения с подстановочными знаками не охватывают границы слов, ноcts:json-property-value-query
для"hello *"
будет соответствовать. Поиск"*"
будет соответствовать, потому что подстановочный знак"*"
сам по себе определен для соответствия значению. Точно так же правила определения основы применяются к каждому термину, поэтому поиск"hello friends"
будет соответствовать, если для запроса включено определение основы, потому что"friends"
соответствует"friend"
.
StructuredQueryBuilder sqb = new StructuredQueryBuilder();
String[] options = {"wildcarded"};
StructuredQueryDefinition queryDefinitionIcs = sqb.value(sqb.jsonProperty("icsList"),
null, options, 1, searchText + "*");
Альтернативой внесению изменений в базу данных может быть создание поля с необходимыми настройками индекса, чтобы облегчить поиск двухсимвольного подстановочного знака для этого поля.
Затем вы можете выполнить поиск в поле с завершающим подстановочным знаком:
cts:search(doc(), cts:field-value-query("icsList", "50* *"))
Ищите по полю вместо jsonProperty:
StructuredQueryDefinition queryDefinitionIcs = sqb.value(sqb.field("icsList"),
null, options, 1, searchText + "* *");