将 search:search 结果集与使用 cts:polygon 地理空间搜索的 cts:search 结果集相交

Intersect search:search result set with cts:search result set that used cts:polygon geospatial search

我必须将地理空间搜索功能添加到现有的应用程序中,该应用程序使用 search:search API 并具有全文搜索和分面搜索功能。我已经阅读了有关扩展搜索 API 的内容,但我现在没有时间。所以,我想我会调整我的代码,以便只做两个结果集的交集(一个由 search:search 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;

Lenti,您 运行 的 XPath 谓词正在将每个 search:result Vhe 与每个 $geo_results Vhe 进行比较——可能需要大量工作,具体取决于地理位置结果被发现。我认为您可能高估了扩展搜索所需的工作量 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>/*
   :) 
};

您还在搜索 API 选项中设置了限制条件:

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

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

资源:

作为 Dave 的好建议的脚注,另一种替代方法是使用 search:parse() 而不是 search:search() 将第二个搜索请求转换为 cts:query 之前 运行宁 cts:search().

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

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

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

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

HTH!

这里是对 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 需要审核。对我来说,这些看起来像是等待发生的性能问题。