针对几个xml文档的组合搜索查询

时间:2015-09-13 10:35:40

标签: xquery marklogic

我在每个图书目录/books/{book_id}/中都有几个xml文档。 /books/{book_id}/basic.xml/books/{book_id}/formats.xml。 第一个是

    <document book_id="{book_id}">
      <title>The book</title>
    </document>

,第二个是

    <document book_id="{book_id}">
      <format>a</format>
      <format>b</format>
      <format>c</format>
    </document>

如何通过一个查询找到/books/目录中format eq 'a'title eq *'book'*的所有图书?当我第一次按cts:search()格式查找所有书籍时,我做了一个变体,然后通过检查basic.xml文件中的标题过滤“for循环”中的结果。

谢谢!

2 个答案:

答案 0 :(得分:3)

此问题列为MarkLogic以及xQuery。为了完整起见,我已经包含了一个单一语句的MarkLogic解决方案:

let $res := cts:search(doc(), cts:and-query(
       (
         cts:element-word-query(xs:QName("title"), '*book*', ('wildcarded'))
         ,
         cts:element-attribute-range-query(xs:QName("document"), xs:QName("book_id"), '=', cts:element-attribute-values(xs:QName("document"), xs:QName("book_id"), (), (), cts:element-value-query(xs:QName("format"), 'b')))
          )
         ) 
)

行。现在让我们分解一下并看看。

注意:此示例在属性book_id上需要一个范围索引

我的工具优势在于,在两种类型的文档中,您在同一名称空间中具有相同的属性。这允许以下内容:

  • 我可以使用单个索引
    • 然后我使用了element_ids列表的元素属性值 - 这受到格式&#39;的限制。元件
    • 上面的book_ids列表用于过滤图书(范围查询)
    • 然后通过标题
    • 进一步过滤
    • 这种方法使用超快的范围索引连接两个文档 - 特别是在book_id的整数值上

应该注意的是,在这个关联案例中,我能够隔离正确的文件,因为标题元素只存在于一种文件中。

现在,让我们看一下同一查询的一个更清晰的例子。

(: I used a word-query so that I could do wildcarded searches for document with 'book' in the title.  This is because your sample has a title 'The Book', yet you search for 'book' so I can olnly conclude that you meant to have wildcard searches :)
let $title-constraint := "*book*"
(: This could also be a sequence :)
let $format-constraint := "a"
(: used for the right-side of the element-range-query :)
let $format-filter := cts:element-attribute-values(xs:QName("document"), xs:QName("book_id"), (), (), cts:element-value-query(xs:QName("format"), $format-constraint))
(: final results :)
let $res := cts:search(doc(), cts:and-query((
                                            cts:element-word-query(xs:QName("title"), $title-constraint, ('wildcarded'))
                                            ,
                                            cts:element-attribute-range-query(xs:QName("document"), xs:QName("book_id"), '=', $format-filter)
                                            )
                             ) )
return $res

答案 1 :(得分:0)

我认为我找到了更好的解决方案

let $book_ids := cts:values(
  cts:element-attribute-reference(xs:QName("document"), xs:QName("book_id") ), 
  (), 
  ("map"), 
  cts:and-query((
    cts:directory-query(("/books/"), "infinity"),
    cts:element-query(xs:QName("title"),"book")
  ))
)
return 
  cts:search(
    /, 
    cts:and-query((
      cts:element-attribute-value-query(xs:QName("document"), xs:QName("book_id"), map:keys($book_ids)),
      cts:element-value-query(xs:QName("format"), "a"),
    ))
  )
相关问题