2016-09-21 148 views
0

我想在MarkLogic中搜索文檔。MarkLogic - 通過最大值/最小值篩選器搜索

我的文件看起來像:

<product xmlns="myns/products"> 
    <id>3114</id> 
    <materialNo xml:lang="en">1.1160</materialNo> 
    <steelName xml:lang="en">SWRCH24K</steelName> 
    <name xml:lang="en">wire, wire rod for cold heading</name> 
    <chemicalProperties> 
    <chemicalProperty> 
     <element>c</element> 
     <min>0.1900</min> 
     <max>0.2500</max> 
    </chemicalProperty> 
    <chemicalProperty> 
     <element>si</element> 
     <min>0.1000</min> 
     <max>0.3500</max> 
    </chemicalProperty> 
    <chemicalProperty> 
     <element>mn</element> 
     <min>1.3500</min> 
     <max>1.6500</max> 
    </chemicalProperty> 
    <chemicalProperty> 
     <element>p</element> 
     <max>0.0300</max> 
    </chemicalProperty> 
    </chemicalProperties> 
</product> 

所以我想通過化學性能的最大/最小值進行搜索。爲此,我使用此xquery搜索(簡單示例):

cts:search(/, cts:and-query(
    (cts:collection-query("test"), 
    cts:element-value-query(
    fn:QName("myns/products", "name"), 
    "wire, wire rod for cold heading"), 
    cts:element-query(
    fn:QName("myns/products", "chemicalProperty"), 
    cts:and-query(
     (cts:element-value-query(
      fn:QName("myns/products", "element"), "c"), 
     cts:or-query(
      (cts:element-range-query(
      fn:QName("myns/products", "max"), "<=", 0.2), 
      cts:and-not-query(
      cts:element-range-query(
       fn:QName("myns/products", "min"), "<=", 0.2), 
      cts:element-value-query(
       fn:QName("myns/products", "max"), "*")))), 
     cts:or-query(
      (cts:element-range-query(
      fn:QName("myns/products", "min"), ">=", 0.1), 
      cts:and-not-query(
      cts:element-range-query(
       fn:QName("myns/products", "max"), ">=", 0.1), 
      cts:element-value-query(
       fn:QName("myns/products", "min"), "*")))))))))) 

問題是上面的查詢將返回示例文檔。 子查詢(而非)用於檢查最大/最小值是否存在。在某些情況下,可能只有最小值或只有最大值。

但是這個文件出界了!

我的數據庫確實有最小值和最大值的元素範圍索引。所有其他設置都是默認設置。

什麼問題?有什麼建議麼。

UPDATE

好了,感謝您的建議,但沒有。啓用價值位置並不能解決問題。然而一個解決方法是刪除了「和不查詢」,並以「和查詢」更換和新的屬性添加到文件:

<chemicalProperty hasMin="0" hasMax="1">... 

索引和查詢這些屬性的工作並返回正確的結果。

+0

如果您有後續問題,請將其作爲單獨的SO問題發佈。如果這個問題是相關的,那麼你可以鏈接到新的問題。 – wst

回答

1

這有可能是因爲你的索引設置,cts:element-query返回true,如果在同一文檔中的任何<chemicalProperty>minmax查詢匹配,而不是受限於單一的<chemicalProperty>。我只希望看到這在未經過濾的搜索,但是,我沒有看到你的電話cts:search的選項。

首先嚐試啓用element value positions,這應該允許數據庫使用索引排除不同元素中的匹配項。

另一種解決方案是使用cts:near-query來限制元素查詢中位置的值。

+1

職位應該解決這個問題。 cts:near-query也需要這些,或者它會像cts:and-query一樣有效。至少,當運行未過濾.. – grtjn

+0

@grtjn我認爲'cts:near-query'需要與'cts:element-query'不同的位置索引嗎?但是,對於問題中明顯過濾的查詢,我有點困惑。鑑於這種行爲,我認爲目前最安全的假設是,OP意外地將其排除在例外之外。 – wst

+0

你是對的,'cts:near-query'需要不同的位置索引。 http://docs.marklogic.com/cts:near-query說:'position位置索引將加快使用cts:near-query的查詢的性能。元素字位置索引將加快使用cts:near-query的元素查詢的性能。' – grtjn

0

問題似乎是您試圖在cts:element-value-query調用中使用通配符,但沒有聲明它們是通配符的。由於沒有任何內容符合文字「*」,因此cts:and-not-query與您的意圖相反。

你想是這樣的:

cts:element-value-query( fn:QName("myns/products", "max"), "*", "wildcarded")

cts:element-value-query

或者,您可以啓用通配符的指標之一,而ML會自動檢測通配符查詢。

如果「通配符」和「unwildcarded」均不存在,則數據庫配置和$文本將確定通配符。如果數據庫啓用了任何通配符索引(「三個字符搜索」,「兩個字符搜索」,「一個字符搜索」或「尾隨通配符搜索」),並且$ text包含通配符'?'或'*',它指定「通配符」。否則它指定「unwildcarded」。

+0

通常不需要聲明通配符選項。如果啓用了任何通配符索引,則當查詢字符串中存在通配符時,「通配符」選項將隱含。 – wst

+0

我從「所有其他設置都是默認設置」中假定沒有任何通配符索引已啓用。 – BenW