2016-09-21 166 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