MarkLogic - поиск в каждом вхождении массива - PullRequest
0 голосов
/ 26 февраля 2019

MarkLogic версия: 9.0-6.2

У меня есть массив в документе json следующим образом.Мне нужно вернуть этот документ, только если адрес электронной почты «test1@testmail.com», а EmailOverrideInd для этого конкретного адреса «N».

"Contacts": [
  {
    "FirstName": "FTest1", 
    "LastName": "LTest1", 
    "Email": "test1@testmail.com", 
    "EmailOverrideInd": "Y"
  },
  {
    "FirstName": "Ftest2", 
    "LastName": "Ltest2", 
    "Email": "test2@testmail.com", 
    "EmailOverrideInd": "N"
  }
]

В приведенном выше примере запрос не должен возвращатьсядокумент в качестве EmailOverrideInd имеет значение «N» для электронного письмавхождение массива.

cts.search(
  cts.andQuery(
    [
      cts.collectionQuery('testcol'),
      cts.jsonPropertyValueQuery('Email', EmailAddr, ['exact']), 
      cts.jsonPropertyValueQuery('EmailOverrideInd', 'N', ['exact'])
    ]
  ),
  ['unfiltered','score-zero']
)

Как я могу ограничить свой поиск каждым вхождением массива?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Одной альтернативой хорошему предложению Дейва было бы создание индекса TDE, который проецирует элементы массива в виде строк.

Укажите идентификатор фрагмента при открытии представления, ограничьте с помощью текущего запроса, отфильтруйте столбцы, чтобыпредставляющие интерес электронные письма, а затем присоедините документы, если требуется другая информация о документе (в противном случае просто используйте строки).

Эскиз общей формы кода:

const docId = op.fragmentIdCol('docId');

const results = op.fromView(yourEmailsSchema, yourEmailsView, '', docId)
  .where(... your existing cts.query to narrow the candidates ...)
  .where(... boolean expression against the columns to get the exact ...)
  .joinDoc('doc', docId)
  .select('doc')
  .result();

См. Также:

http://docs.marklogic.com/guide/app-dev/TDE

и

http://docs.marklogic.com/op.fromView

Надеюсь, что поможет,

0 голосов
/ 27 февраля 2019

Если вы можете рассчитывать на структуру, похожую на ваш пример, вы можете использовать cts.nearQuery.

let emailAddr = "test1@testmail.com";

cts.search(
  cts.andQuery(
    [
      cts.collectionQuery('testcol'),
      cts.nearQuery(
        [
          cts.jsonPropertyValueQuery('Email', EmailAddr, ['exact']), 
          cts.jsonPropertyValueQuery('EmailOverrideInd', 'N', ['exact'])
        ],
        1,
        'ordered'
      ),
    ]
  ),
  ['unfiltered', 'score-zero']
)

Для успешной работы без фильтрации вам нужно включить индекс "словесные позиции".

Параметр 1 для cts.nearQuery означает, что два значения propertyQuery должны находиться в одном слове друг от друга.Обратите внимание, что я использовал «заказанный» вариант.Это может быть необязательно в этом случае, но иногда мне бывает полезно, когда я знаю порядок структуры данных.

Предостережение: я понимаю, как работает подсчет слов в XML-документах, но на самом деле в JSON не так уж много играл.Возможно, вам нужно отрегулировать счет, но я думаю, что 1 здесь правильно.

...