相交搜索:使用cts搜索结果集:使用cts的搜索结果集:多边形地理空间搜索

时间:2015-03-05 13:00:50

标签: full-text-search xquery intersection marklogic cts-search

我不得不将地理空间搜索功能添加到已经存在的应用程序中,该应用程序使用搜索:搜索API并具有全文搜索和分面搜索。我读过有关扩展Search API的内容,但我现在没有时间。所以,我想我会修改我的代码,以便只做两个结果集的交集(一个由搜索返回:搜索API,另一个由cts:search返回,允许cts:polygon搜索) 。不幸的是,交叉点严重降低了执行时间。 是否有更好的方法来优化或加速以下表达式?

$results_fts//search:result[./search:metadata/Vhe eq $geo_results//root/Vhe]

这是我的代码:

declare variable $geo_results := 
let $qr := cts:search(doc(), cts:and-query(($q-geospatial,
            cts:word-query("*", ("case-insensitive","whitespace-insensitive","wildcarded","diacritic-insensitive"))   ))   )  (:Search all * within the polygon:)
return $qr;

declare variable $results_fts := 
let $qrs := search:search($q-text, $options, xs:unsignedLong(xdmp:get-request-field("start","1")), 12000)  (:max page length to get all records:)
return $qrs;

declare variable $results := 
let $qrt := if (xdmp:get-request-field("map-code")) then 
(:intersect geospatial search with the full text search:)
                <search:response>
                  { $results_fts//search:result[./search:metadata/Vhe eq $geo_results//root/Vhe] } 
                  { $results_fts//search:facet }
                  { $results_fts//search:qtext }
                  { $results_fts//search:metrics }
                </search:response>
          else $results_fts
return $qrt;

4 个答案:

答案 0 :(得分:2)

作为Dave的好建议的脚注,另一种选择是使用search:parse()而不是search:search()在运行cts:search之前将第二个搜索请求转换为cts:query ()。

http://docs.marklogic.com/search:parse?q=search:parse&v=8.0&api=true

然后,将cts:query()生成的search:parse()添加到现有cts:and-query()中的子查询列表中,并运行单个搜索。

我不清楚地理空间查询中的cts:word-query(&#34; *&#34;)子句是做什么的,但这与主要点无关。

答案 1 :(得分:1)

Lenti,你正在运行的XPath谓词是比较每一个搜索:结果与每个$ geo_results Vhe相对应 - 可能需要做很多工作,具体取决于找到多少个地理结果。我认为你可能高估了扩展Search API所需的工作量。如果您采用这种方式,MarkLogic可以为您处理优化。

您需要的是自定义约束。您只需要实现解析功能,而不是开始和结束(您需要自定义方面)。看起来你正在使用字符串查询而不是结构化查询,所以像这样:

declare function geo:parse(
  $constraint-qtext as xs:string, 
  $right as schema-element(cts:query))
as schema-element(cts:query)
{
  (: TODO: you don't show above how you construct the geospatial query,
   : but do that here using $right//cts:text as input. 
   :)
  (: If MarkLogic complains that your geospatial query doesn't match
   : the return type, you probably need to serialize it like this: 
       return <root>{$q-geospatial}</root>/*
   :) 
};

您还可以在Search API选项中设置约束:

<constraint name="my-custom">
  <custom facet="false">
   <parse apply="parse" ns="..." at="..." />
  </custom>
</constraint>

...其中ns是“geo:”是上面的前缀的命名空间,at是定义解析函数的库模块的路径。

资源:

答案 2 :(得分:0)

除了Dave和Eriks的建议之外,你还可以做与Erik建议相反的事情:采取cts:查询cts:search,并将其作为附加查询嵌入到搜索的搜索选项中:搜索。您可以在运行时为此重新创建$选项。这样做可以让您利用搜索库提供的所有好处。

HTH!

答案 3 :(得分:0)

这是Geert和Erik提出的想法的一个转折点。我认为这可以最大限度地减少对现有代码的更改。

declare variable $Q-GEO :=
  cts:and-query(
    ($q-geospatial,
     (: TODO This smells funny. :)
     cts:word-query(
       "*",
       ("case-insensitive", "whitespace-insensitive", "wildcarded",
        "diacritic-insensitive")) )) ;

declare variable $Q-FT := cts:query(search:parse($q-text, $options)) ;

search:resolve(
  document { cts:and-query(($Q-GEO, $Q-FT)) }/*,
  $options,
  xs:unsignedLong(xdmp:get-request-field("start", "1")),
  (: TODO Rarely a good idea to fetch so many records :)
  12000)

我同意之前的评论,word-query *12000需要审核。对我来说,那些看似等待发生的性能问题。