Поля с несколькими совпадениями Elasticsearch не включают строку запроса - PullRequest
0 голосов
/ 06 мая 2020

Я выполняю поиск с несколькими совпадениями, используя следующий объект запроса:

{
    _source: [
        'baseline',
        'cdrp',
        'date',
        'description',
        'dev_status',
        'element',
        'event',
        'id'
    ],
    track_total_hits: true,
    query: {
        bool: {
            filter: [{name: "baseline", values: ["1f.0.1.0", "1f.1.8.3"]}],
            should: [
                {
                    multi_match:{
                        query: "national",
                        fields: ["cdrp","description","narrative.*","title","cop"]
                    }
                }
            ]
        } 
    },
    highlight: { fields: { '*': {} } },
    sort: [],
    from: 0,
    size: 50
}

Я ожидаю, что слово «национальный» будет найдено в полях описания или повествования. * Но только одна запись из 2 вернувшихся оправдали мои ожидания. Пытаюсь понять почему.

elasticsearch.config.ts

"settings": {
    "analysis": {
        "analyzer": {
            "search_synonyms": {
                "tokenizer": "whitespace",
                "filter": [
                    "graph_synonyms",
                    "lowercase",
                    "asciifolding"
                ],
            }
        }
    }
},

"mappings": {
    "properties": {
        "description": {
            "type": "text",
            "analyzer": "search_synonyms"
        },
        "narrative": {
            "type":"object",
            "properties":{
                "_all":{
                    "type": "text",
                    "analyzer": "search_synonyms"
                }
            }
        },
    }
}

1 Ответ

0 голосов
/ 07 мая 2020

Если предложение работает как OR, оно не отфильтровывает документы, влияющие на оценку. Документы, которые соответствуют предложению should, получают более высокий балл.

Если вы хотите отфильтровать по множественному соответствию, вы можете переместить его в предложение фильтра

filter: [
           {
              name: "baseline", values: ["1f.0.1.0", "1f.1.8.3"]
           },
           {
               multi_match:
               {
                     query: "national",
                     fields: ["cdrp","description","narrative.*","title","cop"]
               }
           }
        ]

Filter vs Must: - Оба возвращают предложения соответствия документов указано. Фильтр не оценивает документы. Поэтому, если вас не интересует количество документов или порядок возврата документов, вы можете использовать фильтр. Таким образом, оба варианта одинаковы с разницей в оценке.

Документы с большим количеством совпадений оцениваются выше

Multi_match по умолчанию использует best_fields

Находит документы, которые соответствуют любому полю, но использует _score из лучшего поля.

Он использует оценку, возвращенную для поля с максимальным количеством совпадений, для расчета оценки для каждого документа.

Пример

В документе 1 есть совпадения в двух полях, поле 1 (оценка 2), поле 2 (оценка 1)

В документе 2 есть совпадения в одном поле, поле 2 (оценка 3 )

Docu mnet 2 будет иметь более высокий рейтинг, даже если соответствует 1 поле.

Вы можете изменить его на most_fields

Находит документы, соответствующие любому полю и объединяет _score из каждого поля.

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "test",
            "fields": [],
            "type": "most_fields"
          }
        }
      ]
    }
  }
}

Тем не менее документ с меньшим количеством сопоставленных полей может получить более высокий рейтинг из-за высокого балла в поле, вызванного несколькими терминами.

Если вы хотите дать одинаковую оценку одному полю независимо от количества совпавших жетонов. Вам нужно использовать constant_score query

{
  "query": {
    "bool": {
      "should": [
        {
          "constant_score": {
            "filter": {
              "term": {
                "field1": "test"
              }
            }
          }
        },
        {
          "constant_score": {
            "filter": {
              "term": {
                "field2": "test"
              }
            }
          }
        }
      ]
  }
},
  "highlight": {
    "fields": {
      "field1": {},
      "field2": {}
    }
  }
}

Result:

"hits" : [
      {
        "_index" : "index18",
        "_type" : "_doc",
        "_id" : "iSCe6nEB8J88APx3YBGn",
        "_score" : 2.0, --> one score per field matched
        "_source" : {
          "field1" : "test",
          "field2" : "test"
        },
        "highlight" : {
          "field1" : [
            "<em>test</em>"
          ],
          "field2" : [
            "<em>test</em>"
          ]
        }
      },
      {
        "_index" : "index18",
        "_type" : "_doc",
        "_id" : "iiCe6nEB8J88APx3ghF-",
        "_score" : 1.0,
        "_source" : {
          "field1" : "test",
          "field2" : "abc"
        },
        "highlight" : {
          "field1" : [
            "<em>test</em>"
          ]
        }
      },
      {
        "_index" : "index18",
        "_type" : "_doc",
        "_id" : "iyCf6nEB8J88APx3UhF8",
        "_score" : 1.0,
        "_source" : {
          "field1" : "test do",
          "field2" : "abc"
        },
        "highlight" : {
          "field1" : [
            "<em>test</em> do"
          ]
        }
      }
    ]
  }
...