将 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 是定义解析函数的库模块的路径。
资源:
- Creating a Custom Constraint
- Implementing a string query parse function
- Example: Creating a Custom Constraint Geospatial Facet(忽略start-facet和finish-facet函数)
作为 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
需要审核。对我来说,这些看起来像是等待发生的性能问题。
我必须将地理空间搜索功能添加到现有的应用程序中,该应用程序使用 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 是定义解析函数的库模块的路径。
资源:
- Creating a Custom Constraint
- Implementing a string query parse function
- Example: Creating a Custom Constraint Geospatial Facet(忽略start-facet和finish-facet函数)
作为 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
需要审核。对我来说,这些看起来像是等待发生的性能问题。