首页 > 解决方案 > MarkLogic 地理空间查询不返回分数

问题描述

我了解默认情况下地理空间查询不会增加分数,但我发现当添加适当的选项时它们仍然没有:

const jsearch = require('/MarkLogic/jsearch.sjs');  
jsearch.documents()   
        .where(
                 cts.jsonPropertyGeospatialQuery("coordinates",
                 cts.circle(45,cts.point(-28.81354,153.2773)),
                  ["score-function=reciprocal", "slope-factor=10.0","type=long-lat-point","units=km"]
                     ,1.0)


         )
        .slice(0,100)       
      .map({snippet: true})
      .result()

返回以下内容

{
   "results": [
      {
        "uri": "/A/URI/5797f1514689edaf278d2f9e.json", 
         "index": 0, 
         "matches": [
               {
"path": "fn:doc(\"/A/URI/5797f1514689edaf278d2f9e.json\")/object-node()", 
      "matchText": [
           ..."


       ]
}, ...

不包括分数。

谁能解释为什么没有分数或我怎么能得到一个?

请参阅随附的工作区。这是对地理空间教程的修改。我有以下问题。

谁能解释为什么只有cts.search将返回集减少到一个匹配记录?

cts.uris返回所有具有字段坐标但不将它们减少到圆圈内的文档。如果默认情况下查询未过滤,为什么要传递查询?

jsearch 返回与 cts.uris 相同的结果,我可以忍受这个但为什么所有分数都为 0 一个应该正好在圆的中心。

工作区

标签: geospatialmarklogic

解决方案


跟进,因为自从我的原始答案以来问题已经更新。工作区有助于了解正在发生的事情。

您正在创建一个地理空间路径索引on/location/coords但正在使用cts.jsonPropertyGeospatialQuery,它不能利用该索引。如果没有适合您的地理空间查询条件的后备索引,您将需要依赖过滤。

相反,您应该使用cts.pathGeospatialQuery,以便它可以利用地理空间索引来提供快速准确的未过滤结果,而不必依赖过滤。

cts.pathGeospatialQuery("/location/coords", circle, ['units=km'], 1.0)

至于为什么在score搜索结果中没有返回分数,似乎没有返回分数的原因是因为type=long-lat-point指定了错误的选项。索引值为type=point

当我指定type=point或删除 type 选项时,将返回一个非零分数。


应用.map({snippet: true})时,jsearch 实现将仅包含那些值存在且不等于的属性0

如果删除.map({snippet: true}),您将在结果中看到scoreconfidencefitness

如果您发现它们确实缺失或等于0并且您仍然希望这些属性出现在您的结果中,您可以在事后有条件地添加它们:

const jsearch = require('/MarkLogic/jsearch.sjs');  
let result = jsearch.documents()   
        .where(
          cts.jsonPropertyGeospatialQuery("coordinates",
             cts.circle(45,cts.point(-28.81354,153.2773)),
             ["score-function=reciprocal", "slope-factor=10.0","type=long-lat-point","units=km"],
             1.0)
         )  
        .slice(0,100)  
        .map({snippet: true})
        .result();

result.results.forEach(r => ["score","fitness","confidence"].forEach(p => r[p] ? null : r[p]=0));

result;

推荐阅读