2017-02-20 14 views
1

Мы создаем корпоративное приложение с ML в качестве исходного кода. Многие экраны в приложении имеют выпадающие списки, которые требуют различных значений элементов внутри документов. Таким образом, мы создали индекс диапазона элементов для этих элементов и подготовили код для получения отдельных значений с использованием индекса диапазона.Ограничение диапазона индексов по элементам в документах определенной коллекции

Теперь мы разделяем документы в разные коллекции логически - как «basedata» коллекция, в которой хранятся все документы базы данных приложений и коллекция «transactiondata», которая содержит все входящие/исходящие транзакции для нашего приложения.

Теперь необходимо ограничить индекс диапазона только базовыми документами сбора данных, а не документами транзакционных данных.

Например: если у нас есть индекс диапазона элементов LocalName = «EntityName» мы не хотим индекса диапазон, который будет построен для значений EntityName присутствующих в документах транзакционного сбора данных. Мы хотим, чтобы различные значения «entityName» встречались только в документах, прикрепленных к коллекции basedata.

Как мы можем достичь этого?

Edit:

Спасибо Давид и grtjn.

Это то, что мы сейчас делаем в Java слой: Код ниже правильно возвращая различные имена для поля EntityName, который имеет индекс диапазона, созданный.

String valueOptionString = 
    " <search:options xmlns:search="http://marklogic.com/appservices/search"> 
     <search:values name="entityName"> 
      <search:range type="xs:string"> 
       <search:element name="entityName"> 
       </search:element> 
      </search:range> 
     </search:values> 
    </search:options> ";  

QueryManager queryMgr = client.newQueryManager(); 
    QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager(); 
    optionsMgr.writeOptions("DistinctValues", new StringHandle(valueOptionString)); 

    ValuesDefinition vdef = queryMgr.newValuesDefinition("entityName", "DistinctValues"); 
    ValuesHandle vh = queryMgr.values(vdef, new ValuesHandle()); 

    for (CountedDistinctValue value : vh.getValues()) { 
     System.out.println("Distinct value is :: " + 
      value.get("xs:string", String.class)); 
    } 

Как вы видите, я не устанавливать коллекцию в любом месте на queryMgr.values ​​(); Основываясь на предложениях условии, что я попытался добавить коллекцию ограничение ИНТ на valueOptionString, но он не работает. Правильно ли это? Есть ли другой способ встречается из

<search:options xmlns:search="http://marklogic.com/appservices/search"> 
<search:values name="createdBy"> 
    <search:range type="xs:string"> 
     <search:element name="createdBy"/> 
    </search:range> 
    <search:collection> 
     <search:uri>basedaata</search:uri> 
     <search:uri>tansactiondata</search:uri> 
    </search:collection> 
</search:values> 
</search:options> 

Ошибка:

Local message: /config/query write failed: Bad Request. Server Message: RESTAPI-INVALIDCONTENT: (err:FOER0000) Invalid content: Op 
eration results in invalid Options: XDMP-VALIDATEUNEXPECTED: (err:XQDY0027) validate strict { $opt } -- Invalid node: Found text{"basedaata..."} but expected() at fn:doc("") 

EDIT 2:

Основываясь на ответах ниже я обновил свой код, чтобы включить «additional- запрос "в необязательном запросе, чтобы содержать различные возвращаемые значения. Однако это выглядит дополнительная часть запроса игнорируется и не работает, как ожидалось

Изменено дополнительный запрос:

<search:options xmlns:search="http://marklogic.com/appservices/search"> 
    <search:values name="entityName"> 
     <search:range type="xs:string"> 
      <search:element name="entityName"/> 
     </search:range> 
    </search:values> 
    <search:additional-query> 
     <cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
      <cts:uri>basedata</cts:uri> 
      <cts:uri>DistinctValueTest</cts:uri> 
     </cts:collection-query> 
    </search:additional-query> 
</search:options> 

Ниже приведены документы, у меня есть. Также у меня есть индекс диапазона элементов в поле entityName ..

Документ в коллекции basedata:

<?xml version="1.0" encoding="UTF-8"?> 
<entity> 
    <entityName>Company</entityName> 
    <createdBy>CompanyOwner</createdBy> 
    <createdDate>2017-01-01T05:56:35.360Z</createdDate> 
    <status>Active</status> 
    <entityattributes> 
     <entityattribute> 
     </entityattribute> 
    </entityattributes> 
</entity> 

Теперь создала коллекцию под названием тест DistinctValueTest и добавлен документ для целей тестирования в этой коллекции.

Документ в коллекции DistinctValueTest:

<?xml version="1.0" encoding="UTF-8"?> 
<entity> 
    <entityName>DistinctValueTestEntity</entityName> 
    <createdBy>DistinctValuteSystemNew</createdBy> 
    <createdDate>2017-01-03T05:56:35.360Z</createdDate> 
    <status>Active</status> 
    <entityattributes> 
     <entityattribute> 
     </entityattribute> 
    </entityattributes> 
</entity> 

Выход программы: Компания, DistinctValueteSystemNew когда обе коллекции поставляются в дополнительной секции запроса

<cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
    <cts:uri>basedata</cts:uri> 
    <cts:uri>DistinctValueTest</cts:uri> 
</cts:collection-query 

Однако, если я только предоставляют сборку «basedata» в cts: uri она по-прежнему показывает продукцию как Company, DistinctValueteSystemNew, а не просто Компания

<cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
    <cts:uri>basedata</cts:uri> 
</cts:collection-query 
+0

Возможно, было бы лучше разместить часть редактирования в отдельном вопросе .. – grtjn

ответ

3

Вместо того, чтобы создавать несколько индексов для каждой комбинации критериев, вы объединяете индексы при чтении. Функция cts:values принимает 4-й параметр, который представляет запрос, который будет обрезать фрагменты, из которых будут получены значения. В вашем случае это будет выглядеть примерно так:

cts:values(
    cts:element-reference(xs:QName("entityName")), 
(), 
(), 
    cts:collection-query("basedata") 
) 

Аналогичные эффекты могут быть достигнуты с немного более абстрактной search:values функции, и /v1/values REST конечными точками.

HTH!

+0

Спасибо David/grtjn. Я попробовал это и обновил свой вопрос с проблемой, с которой я столкнулся. Пожалуйста, дайте мне знать. Заранее спасибо. – nocoder

1

Основываясь на ответе grtjn и обновленном вопросе, простой способ ограничить значения, возвращаемые в конкретную коллекцию, с добавлением additional-query к вашим параметрам.

<search:options xmlns:search="http://marklogic.com/appservices/search"> 
    <search:values name="createdBy"> 
    <search:range type="xs:string"> 
     <search:element name="createdBy"/> 
    </search:range> 
    </search:values> 
    <search:additional-query> 
    <cts:collection-query xmlns:cts="http://marklogic.com/cts"> 
     <cts:uri>basedata</cts:uri> 
     <cts:uri>transactiondata</cts:uri> 
    </cts:collection-query> 
    </search:additional-query> 
</search:options> 

additional-query добавляется каждый запрос запуска с этим набором опций.

+0

Дополнительный запрос - это один из способов работы с этим, но ваш код Java сделает вызов '/ v1/values ​​/ createdBy' под обложками. Эта конечная точка REST принимает параметр запроса 'collection', параметр' q' и параметр 'structuredQuery', все из которых могут быть использованы для получения того же эффекта, что и дополнительный запрос, но более динамичным способом. Должны быть способы сообщить объекту 'queryMgr' пройти дополнительные ограничения. (Любой, кто мог бы знать, как это сделать?) – grtjn

+0

@grtjn <дополнительный-запрос> с работает не так, как ожидалось. Обновлен мой исходный вопрос. Проверьте Edit 2. – nocoder

+0

@ Дайте какое-либо обновление по проблеме, с которой я столкнулся в Редактировании 2 моего вопроса выше? Спасибо за вашу помощь. – nocoder