Статьи

Использование параметра Solmax Dismax Tie

Синтаксический анализатор запросов Dismax уже давно работает с Solr. В большинстве случаев мы используем такие параметры, как qf , pf  или mm,  забывая об очень полезном параметре, который позволяет нам контролировать, как обрабатываются поля с более низкой оценкой —  параметр tie .

Галстук

Параметр связи  позволяет контролировать, как нижние поля оценки влияют на оценку для данного слова. Если мы устанавливаем галстук  параметр в значение 0.0, в процессе расчета балла, только поля , которые были забиты самым высоким будут иметь значение. Однако, если мы установим его на 0,99, поля с более низким баллом будут иметь почти такое же влияние на счет, как и поле с наивысшим баллом. Итак, давайте проверим, действительно ли это работает.

Структура данных и пример данных

Для того, чтобы проверить , как связь  параметров работы я выбрал простую структуру индекса , которая описывала бы товары в интернет-магазине, конечно , в простом режиме:

<field name="id" type="string" indexed="true" stored="true" required="true" />
<field name="title" type="text_ws" indexed="true" stored="true" />
<field name="description" type="text_ws" indexed="true" stored="true" />
<field name="author" type="text_ws" indexed="true" stored="true" multiValued="true" />

Тип  text_ws  был определен следующим образом:

<fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100">
 <analyzer>
  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
  <filter class="solr.LowerCaseFilterFactory"/>
 </analyzer>
</fieldType>

Примеры документов выглядят так:

<add>
 <doc>
  <field name="id">1</field>
  <field name="title">First test book</field>
  <field name="description">This is a description of the first test book by Joe and Jane Blow</field>
  <field name="author">Joe Blow</field>
  <field name="author">Jane Blow</field>
 </doc>
 <doc>
  <field name="id">2</field>
  <field name="title">Second test book</field>
  <field name="description">This is a description of the second test book by Joe Blow</field>
  <field name="author">Joe Blow</field>
 </doc>
</add>

Галстук == 0,01 результат

Давайте начнем тест. Первый запрос был следующий:

defType=dismax&qf=title^1000 description author^10&tie=0.01&fl=id,score&debugQuery=on&indent=true&q=joe blow book

Вышеуказанное привело к следующим результатам Solr (визуализация — http://explain.solr.pl/explains/cf0wnkpj ):

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">8</int>
  <lst name="params">
    <str name="fl">id,score</str>
    <str name="debugQuery">on</str>
    <str name="indent">true</str>
    <str name="tie">0.01</str>
    <str name="q">joe blow book</str>
    <str name="qf">title^1000 description author^10</str>
    <str name="defType">dismax</str>
  </lst>
</lst>
<result name="response" numFound="2" start="0" maxScore="0.07342677">
  <doc>
    <float name="score">0.07342677</float>
    <str name="id">2</str>
  </doc>
  <doc>
    <float name="score">0.073365316</float>
    <str name="id">1</str>
  </doc>
</result>
<lst name="debug">
  <str name="rawquerystring">joe blow book</str>
  <str name="querystring">joe blow book</str>
  <str name="parsedquery">+((DisjunctionMaxQuery((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.01) DisjunctionMaxQuery((author:blow^10.0 | title:blow^1000.0 | description:blow)~0.01) DisjunctionMaxQuery((author:book^10.0 | title:book^1000.0 | description:book)~0.01))~3) ()</str>
  <str name="parsedquery_toString">+(((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.01 (author:blow^10.0 | title:blow^1000.0 | description:blow)~0.01 (author:book^10.0 | title:book^1000.0 | description:book)~0.01)~3) ()</str>
  <lst name="explain">
    <str name="2">
0.07342677 = (MATCH) sum of:
  0.07342677 = (MATCH) sum of:
    8.957935E-4 = (MATCH) max plus 0.01 times others of:
      8.9543534E-4 = (MATCH) weight(author:joe^10.0 in 1), product of:
        0.0024097771 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:joe in 1), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.5817415E-5 = (MATCH) weight(description:joe in 1), product of:
        2.4097772E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 1), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    8.957935E-4 = (MATCH) max plus 0.01 times others of:
      8.9543534E-4 = (MATCH) weight(author:blow^10.0 in 1), product of:
        0.0024097771 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:blow in 1), product of:
          1.0 = tf(termFreq(author:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.5817415E-5 = (MATCH) weight(description:blow in 1), product of:
        2.4097772E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 1), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    0.07163518 = (MATCH) max plus 0.01 times others of:
      0.07163482 = (MATCH) weight(title:book^1000.0 in 1), product of:
        0.2409777 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 1), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=1)
      3.5817415E-5 = (MATCH) weight(description:book in 1), product of:
        2.4097772E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 1), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
</str>
    <str name="1">
0.073365316 = (MATCH) sum of:
  0.073365316 = (MATCH) sum of:
    7.1670645E-4 = (MATCH) max plus 0.01 times others of:
      7.163483E-4 = (MATCH) weight(author:joe^10.0 in 0), product of:
        0.0024097771 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(author:joe in 0), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.5817415E-5 = (MATCH) weight(description:joe in 0), product of:
        2.4097772E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 0), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.0010134276 = (MATCH) max plus 0.01 times others of:
      0.0010130694 = (MATCH) weight(author:blow^10.0 in 0), product of:
        0.0024097771 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.42039964 = (MATCH) fieldWeight(author:blow in 0), product of:
          1.4142135 = tf(termFreq(author:blow)=2)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.5817415E-5 = (MATCH) weight(description:blow in 0), product of:
        2.4097772E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 0), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.07163518 = (MATCH) max plus 0.01 times others of:
      0.07163482 = (MATCH) weight(title:book^1000.0 in 0), product of:
        0.2409777 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 0), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=0)
      3.5817415E-5 = (MATCH) weight(description:book in 0), product of:
        2.4097772E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 0), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    </str>
  </lst>
</lst>
</response>

Первый документ

Второй документ

Что мы можем сказать по этому поводу?

Как вы можете видеть, когда мы проходили мимо 0,01 значения для галстука  параметра, только те поля , которые имеют наибольшее количество баллов для данного слова запроса являются наиболее влиятельными. Хорошим примером такого поведения является книжное  слово в первом документе в списке результатов. Оценка для этого слова — 0,07163518, которая была рассчитана как сумма поля с наибольшим количеством очков (  поле заголовка ) и сумма остальных полей, умноженная на ничью.

Галстук == 0,99 результат

Второй запрос, отправленный Solr, выглядел следующим образом:

defType=dismax&qf=title^1000 description author^10&tie=0.99&fl=id,score&debugQuery=on&indent=true&q=joe blow book

В результате были получены следующие результаты Solr: (визуализация — http://explain.solr.pl/explains/1w7b06lv ):

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">15</int>
  <lst name="params">
    <str name="fl">id,score</str>
    <str name="debugQuery">on</str>
    <str name="indent">true</str>
    <str name="tie">0.99</str>
    <str name="q">joe blow book</str>
    <str name="qf">title^1000 description author^10</str>
    <str name="defType">dismax</str>
  </lst>
</lst>
<result name="response" numFound="2" start="0" maxScore="0.07352995">
  <doc>
    <float name="score">0.07352995</float>
    <str name="id">2</str>
  </doc>
  <doc>
    <float name="score">0.0734685</float>
    <str name="id">1</str>
  </doc>
</result>
<lst name="debug">
  <str name="rawquerystring">joe blow book</str>
  <str name="querystring">joe blow book</str>
  <str name="parsedquery">+((DisjunctionMaxQuery((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.99) DisjunctionMaxQuery((author:blow^10.0 | title:blow^1000.0 | description:blow)~0.99) DisjunctionMaxQuery((author:book^10.0 | title:book^1000.0 | description:book)~0.99))~3) ()</str>
  <str name="parsedquery_toString">+(((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.99 (author:blow^10.0 | title:blow^1000.0 | description:blow)~0.99 (author:book^10.0 | title:book^1000.0 | description:book)~0.99)~3) ()</str>
  <lst name="explain">
    <str name="2">
0.07352995 = (MATCH) sum of:
  0.07352995 = (MATCH) sum of:
    9.308678E-4 = (MATCH) max plus 0.99 times others of:
      8.9540955E-4 = (MATCH) weight(author:joe^10.0 in 1), product of:
        0.0024097078 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:joe in 1), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.581638E-5 = (MATCH) weight(description:joe in 1), product of:
        2.4097077E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 1), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    9.308678E-4 = (MATCH) max plus 0.99 times others of:
      8.9540955E-4 = (MATCH) weight(author:blow^10.0 in 1), product of:
        0.0024097078 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:blow in 1), product of:
          1.0 = tf(termFreq(author:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.581638E-5 = (MATCH) weight(description:blow in 1), product of:
        2.4097077E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 1), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    0.071668215 = (MATCH) max plus 0.99 times others of:
      0.07163276 = (MATCH) weight(title:book^1000.0 in 1), product of:
        0.24097076 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 1), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=1)
      3.581638E-5 = (MATCH) weight(description:book in 1), product of:
        2.4097077E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 1), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
</str>
    <str name="1">
0.0734685 = (MATCH) sum of:
  0.0734685 = (MATCH) sum of:
    7.517859E-4 = (MATCH) max plus 0.99 times others of:
      7.1632763E-4 = (MATCH) weight(author:joe^10.0 in 0), product of:
        0.0024097078 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(author:joe in 0), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.581638E-5 = (MATCH) weight(description:joe in 0), product of:
        2.4097077E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 0), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.0010484984 = (MATCH) max plus 0.99 times others of:
      0.0010130403 = (MATCH) weight(author:blow^10.0 in 0), product of:
        0.0024097078 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.42039964 = (MATCH) fieldWeight(author:blow in 0), product of:
          1.4142135 = tf(termFreq(author:blow)=2)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.581638E-5 = (MATCH) weight(description:blow in 0), product of:
        2.4097077E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 0), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.071668215 = (MATCH) max plus 0.99 times others of:
      0.07163276 = (MATCH) weight(title:book^1000.0 in 0), product of:
        0.24097076 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 0), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=0)
      3.581638E-5 = (MATCH) weight(description:book in 0), product of:
        2.4097077E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 0), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    </str>
  </lst>
</lst>
</response>

Первый документ

Второй документ

Что мы можем сказать по этому поводу?

Как видите, результат оценки документов изменился. Давайте посмотрим на тот же документ и то же  слово книги . В данном случае мы отправили 0,99 в качестве значения параметра связывания, и значение оценки этого слова увеличилось по сравнению с показателем при использовании связи  0,01. Конечно, изменение не только потому , что связь  параметров , но и из — за нормализации, но давайте забудем об этом, чтобы все было просто :)так, во втором случае, мы видим , партитуру 0.071668215, что партитура заголовка  поля суммируются со счетом других полей , умноженных на 0,99 ( галстук  значения параметра).

Подводить итоги

Как вы можете видеть, галстук  параметр позволяет, чтобы контролировать , как оценку рассчитываются для DisjunctionMaxQuery. В крайних случаях, когда мы хотим, чтобы только поля с наибольшим количеством очков вносили вклад в общую оценку, мы можем установить параметр связи равным 0.0. Tie  позволяет нам контролировать, как мы хотим обрабатывать поля с низкой оценкой, когда вычисляется оценка документов и, таким образом, где они находятся в списке результатов, которые мы получаем от Solr при использовании анализатора запросов Dismax.

В случае, если вы трясете

Если вам интересно, что мы использовали для показа вам диаграмм — перейдите на  http://explain.solr.pl/help и посмотрите, может быть,  http://explain.solr.pl/ может быть полезным в вашем случае.

Источник: 
http://solr.pl/en/2012/02/06/what-can-we-use-dismax-tie-parameter-for