Как создать правильный запрос с подстановочными знаками в базе данных Marklogic с помощью Java?

У меня проблема с неправильными результатами при отправке запроса с подстановочными знаками в моем проекте Java. В моей базе данных Marklogic я сохранил несколько файлов json с одинаковой структурой. Я хочу получить те jsons, которые в поле с именем «icsList» (это список строк) начинаются с заданной строки.

Пример icsList в json выглядит так:

  • "icsList": ["11.040.40", "12.50.80"]
  • "icsList": ["12.50.60"]
  • "icsList": ["50.010.10"]

Результаты моего примера:

Запрос - Строка "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>
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы включите двухсимвольный поиск в базе данных, вы можете искать «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 + "* *");

Другие вопросы по теме