如何用cts查询排除含特定元素的文档及过滤指定XML文件?
Hey there! Let's tackle your two questions one by one, with practical MarkLogic-focused solutions:
To exclude documents that include a particular element, you'll want to combine cts:not-query() with cts:element-query(). The cts:element-query() targets all documents that have the specified element, and wrapping it in cts:not-query() inverts that match to exclude those documents.
For example, if you want to exclude any document containing the <keystore-metrics> element, your query would look like this:
cts:search(collection(), cts:not-query( cts:element-query(xs:QName("keystore-metrics"), cts:and-query(())) ) )
xs:QName("keystore-metrics")specifies the element you want to exclude (adjust the namespace if your element uses one)cts:and-query(())acts as a "match any" condition for the element—meaning any document with that element, regardless of its content, will be excluded. If you need to narrow it down further (e.g., exclude only elements with specific child elements), you can replace the emptycts:and-query()with more specific conditions.
keystore-raw.xml URI Without a For-Loop Instead of iterating with a for-loop, you can leverage MarkLogic's built-in query functions to filter the URI list either at the time of fetching (most efficient) or by filtering an existing URI sequence.
Option 1: Filter During URI Fetch (Best Practice)
If you're using cts:uris() to get the list directly from the meters database, add a cts:not-query() to exclude the specific document URI:
cts:uris( (), (), cts:and-query(( cts:collection-query("meters"), // Your existing collection filter cts:not-query(cts:document-query("keystore-raw.xml")) // Exclude the unwanted URI )) )
This avoids fetching the unwanted URI altogether, which is more performant than fetching all URIs and then filtering.
Option 2: Filter an Existing URI Sequence
If you already have a variable holding the full URI list (e.g., $uri-list), use XQuery's sequence filtering to remove the unwanted entry without a loop:
$uri-list[not(. = "keystore-raw.xml")]
This uses a predicate to keep only URIs that don't match the unwanted one. If you need to exclude documents based on their content (e.g., any document with <keystore-metrics> element), you can combine cts:document-query() with cts:not-query() as in Option 1, or use fn:filter() with a check:
fn:filter($uri-list, function($uri) { not(cts:contains(fn:doc($uri), cts:element-query(xs:QName("keystore-metrics"), cts:and-query(())))) })
But note that fetching each document to check its content is less efficient than filtering at the URI level with CTS queries.
内容的提问来源于stack exchange,提问作者bosari

