2016-07-25 2 views
2

Мои документы хранятся в формате JSON в MarkLogic, как это (я удалить ненужные атрибуты для моего случая):MarkLogic (Nodejs API) - Поиск документов, которые соответствуют 2 (или более) условий в массиве объектов атрибут

{ 
    documentId: '', 
    languages: [{ 
    locale: 'en_UK', 
    content: { 
     translated: 'true', 
    } 
    }, { 
    locale: 'de_DE', 
    content: { 
     translated: 'false', 
    } 
    }, {...}], 
} 

Редактировать: Кажется, что мои «бесполезные» атрибуты вызывают некоторые проблемы. Вот мой подробный объект.

{ 
    documentId: '', 
    /* 4 attrs */, 
    languages: [{ 
     locale: 'en_UK', 
     attr: '', 
     content: { 
     /* 14 attrs */, 
     translated: true, 
     /* 2 or 4 attrs */, 
     } 
    }, { 
     locale: 'de_DE', 
     attr: '', 
     content: { 
     /* 14 attrs */, 
     translated: false, 
     /* 2 or 4 attrs */, 
     } 
    }, {...} 
    ], 
    /* 0 or 2 attrs */ 
} 

Я пытаюсь найти все документы, которые имеют по крайней мере один объект в языках где локаль = 'en_UK' и content.translated = истина с

var query = 
    qb.where(
    qb.directory('myDocuments'), 
    qb.scope(
     qb.property('languages'), 
     qb.and(
     qb.scope(qb.property('code'), qb.term('en_UK')), 
     qb.scope(qb.property('translated'), qb.term('true')) 
    ), 
     qb.fragmentScope('properties') 
    ) 
); 

и

qb.where(
    qb.directory(myDocuments'), 
    qb.scope(qb.property('languages'), 
    qb.propertiesFragment(
     qb.value(
     qb.property('languages'), 
     qb.and(
      qb.scope(qb.property('code'), qb.term('en_UK')), 
      qb.scope(qb.property('translated'), qb.term('true')) 
     ) 
    ) 
    ) 
) 
) 

но в обоих случаях запрос возвращает docume nts, ​​которые соответствуют 2 условиям во всем документе, а не в каждом объекте Языки массив.

Я прочитал документацию, но ничего не нашел. У вас есть идеи, как я могу сделать свой запрос?

Редактировать: Я пробую ближайший запрос, но он не работает. Это не соответствует хорошим документам.

qb.where(
    qb.directory(config.marklogicConfiguration.product), 
    qb.scope(qb.property('languages'), 
    qb.near(
     qb.and(
     qb.scope(qb.property('code'), qb.term('ja_JP')), 
     qb.scope(qb.property('translatedInTheLanguage'), qb.term('true')) 
    ), 
     1, 
     qb.weight(0), 
     qb.ordered(true) 
    ) 
) 
) 

Я спрошу, могу ли я изменить структуру объекта.

edit2: Наконец, я использую запрос Xquery, чтобы получить правильный результат.

xdmp:directory("/product/direcory/")/languages[code eq "ja_JP" and content/translated eq "true"] ! root(.) 

В моем случае, я использую для эк содержания/переведено состояния, потому что мои булев хранятся в виде строки. ! корень (.): Возвращает весь объект, а не только языковые объекты, которые соответствуют условию [код экв «ja_JP» и содержание/переведено эк «истинный»]

+0

Выражения XPath, как в edit2, всегда будут работать с фильтрованным режимом, и это может ухудшиться. – grtjn

ответ

2

Попробуйте использовать near-query, один от Location Qualifiers available in structured queries. Предоставьте свой язык и переведенные запросы, укажите distance: 1 и ordered: true. Обратите внимание, что это будет зависеть от того, где были удалены «ненужные атрибуты».

Если это не сработает, вам, вероятно, понадобится ввести еще один слой в вашу структуру.

{ 
    documentId: '', 
    languages: [{ 
    item: { 
     locale: 'en_UK', 
     content: { 
     translated: 'true', 
     } 
    } 
    }, { 
    item: { 
     locale: 'de_DE', 
     content: { 
     translated: 'false', 
     } 
    } 
    }, {...}], 
} 

Это не очень красиво, но это позволит вам запустить container-query.

+1

При использовании ближайших запросов обязательно включите соответствующие индексы позиции. – grtjn

Смежные вопросы