【问题标题】:poor search performance for certain wildcard queries某些通配符查询的搜索性能不佳
【发布时间】:2016-06-06 02:44:56
【问题描述】:

我在使用通配符搜索某些字母组合时遇到性能问题,我不确定我还需要做些什么来改进它。我所有的文档都遵循如下所示的信封模式。

<pdbe:person-envelope>
    <person xmlns="http://schemas.abbvienet.com/people-db/model">
        <account>
            <domain/>
            <username/>
        </account>
        <upi/>
        <title/>
        <firstName>
            <preferred/>
            <given/>
        </firstName>
        <middleName/>
        <lastName>
            <preferred/>
            <given/>
        </lastName>
    </person>
    <pdbe:raw/>
</pdbe:person-envelope>

我定义了一个名为 name 的字段,其中包括 firstName 和 lastName 路径:

{
  "field-name": "name",
  "field-path": [
    {
      "path": "/pdbe:person-envelope/pdbm:person/pdbm:firstName",
      "weight": 1
    },
    {
      "path": "/pdbe:person-envelope/pdbm:person/pdbm:lastName",
      "weight": 1
    }
  ],
  "trailing-wildcard-searches": true,
  "trailing-wildcard-word-positions": true,
  "three-character-searches": true
}

当我使用 search:search 进行一些查询时,有些返回速度很快,而另一些返回速度较慢。这是过滤后的查询。

search:search("name:ha*",
  <options xmlns="http://marklogic.com/appservices/search">
    <constraint name="name">
      <word>
        <field name="name"/>
      </word>
    </constraint>
    <return-plan>true</return-plan>
  </options>
  )

我可以从查询计划中看到,它将过滤数据库中的所有 136547 个片段。但是这个查询很快。

<search:query-resolution-time>PT0.013205S</search:query-resolution-time>
<search:snippet-resolution-time>PT0.008933S</search:snippet-resolution-time>
<search:total-time>PT0.036542S</search:total-time>

但是,搜索 name:tj* 需要很长时间,并且还会过滤掉所有 136547 个片段。

<search:query-resolution-time>PT6.168373S</search:query-resolution-time>
<search:snippet-resolution-time>PT0.004935S</search:snippet-resolution-time>
<search:total-time>PT12.327275S</search:total-time>

我在两者上都有相同的索引。当我专门通过字段约束进行搜索时,是否应该启用其他索引?一般来说,我在数据库本身上启用了这些其他索引。

"collection-lexicon": true,
  "triple-index": true,
  "word-searches": true,
  "word-positions": true

我尝试进行未过滤的查询,但这并没有帮助,因为我在整个文档中找到了一堆匹配项,而不是我想要的字段。我什至尝试将根片段设置为我的 person 元素,但这似乎没有帮助。

 "fragment-root": [
    {
      "namespace-uri": "http://schemas.abbvienet.com/people-db/model",
      "localname": "person"
    }
  ]

感谢您的任何想法。

【问题讨论】:

    标签: search wildcard marklogic marklogic-8


    【解决方案1】:

    如果您想对 person 元素使用可搜索的表达式,并且大多数情况下,如果它在一个文档中出现多次,那么片段根会很有帮助。它不会使您当前的搜索限制在该元素上。

    在您的情况下,您启用了许多相关选项,但通配符选项仅适用于 4 个以上字符。如果要搜索字符较少的通配符,则需要启用三、二和一字符搜索选项。

    上面提到的搜索短语都包含两个带有通配符的字符。由于您只启用了三个字符选项,因此它必须依赖过滤。有些跑得快,有些慢的事实可能是因为缓存。如果您重复相同的查询,MarkLogic 将从缓存中返回结果。

    对于性能测试,您要么必须定期重新启动 MarkLogic 以刷新缓存,要么搜索(半)随机字符串以避免 MarkLogic 能够缓存。或者两者兼而有之..

    HTH!

    【讨论】:

    • 除了Geert所说的,还有一些情况,除了添加2和3字符通配符选项,还可以考虑保留设置are-is,在元素上引入单词词典/field 有问题,然后您基本上根据元素词匹配进行术语扩展。同样,这取决于您的最终用例。您可以将此方法作为自定义约束插入这甚至可以使用诸如 cts:field-word-match 上的渴望选项之类的东西进行调整,以及直接通过每个森林进行处理。哪个更高效/更快?您必须进行测试和调整。
    • 感谢 cmets。我实际上将其用作自定义约束。在搜索选项(用于自动完成)中,我将覆盖术语处理以扩展以搜索这些特定字段。这是自动完成功能,可以在用户输入时快速找到合适的人。这可以是名字/姓氏、用户名或内部标识符。出于某种原因,我以为我在某处读到启用三字符搜索也可以处理两个字符和一个字符的情况,但我可能误读了这一点。启用这些索引解决了这个问题。
    • 我知道我现在在哪里误读了。文档说“如果您有三个字符搜索和一个单词词典,则不需要此索引。”正如@DavidEnnis 提到的,我可以添加单词词典,但我没有。
    猜你喜欢
    • 1970-01-01
    • 2011-07-14
    • 2019-03-08
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多