Elasti c Поиск нечетких запросов неожиданных результатов - PullRequest
0 голосов
/ 03 марта 2020

У меня есть 2 индекса, города и места. У мест 1 у вас есть такое отображение:

{
    "mappings": {
        "properties": {
            "cityId": {
                "type": "integer"
            },
            "cityName": {
                "type": "text"
            },
            "placeName": {
                "type": "text"
            },
            "status": {
                "type": "keyword"
            },
            "category": {
                "type": "keyword"
            },
            "reviews": {
                "properties": {
                    "rating": {
                        "type": "long"
                    },
                    "comment": {
                        "type": "keyword"
                    },
                    "user": {
                        "type": "nested"
                    }
                }
            }
        }
    }
}

И индекс города отображается следующим образом:

{
    "mappings": {
        "properties": {
            "state": {
                "type": "keyword"
            },
            "postal": {
                "type": "keyword"
            },
            "phone": {
                "type": "keyword"
            },
            "email": {
                "type": "keyword"
            },
            "notes": {
                "type": "keyword"
            },
            "status": {
                "type": "keyword"
            },
            "cityName": {
                "type": "text"
            },
            "website": {
                "type": "keyword"
            },
            "cityId": {
                "type": "integer"
            }
        }
    }
}

Изначально у нас был один документ, в который были встроены города, но у меня был проблема поиска в массиве вложенных мест, поэтому я изменил структуру на эту, я хочу иметь возможность искать и cityName, и placeName в одном запросе с нечеткостью. У меня есть город, включающий в себя слово «Сварщик», а также в некоторых местах в этом месте есть слово «Сварщик», которое имеет тип: текст. Однако при поиске сварщика оба следующих запроса (см. Ниже) не возвращают эти документы, поиск сварщиков ИЛИ сварщика возвращает эти документы. Я не уверен, почему сварщик не будет соответствовать сварщику *. Я не указывал никакой анализатор при создании обоих индексов, и при этом я не определяю его явно в запросе, может ли кто-нибудь помочь мне с этим запросом, чтобы он вел себя как ожидалось:

Запрос 1: индекс = места


{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "placeName": {
                            "query": "welder",
                            "fuzziness": 20
                        }
                    }
                },
                 {
                    "match": {
                        "cityName": {
                            "query": "welder",
                            "fuzziness": 20
                        }
                    }
                }

            ]
        }
    }
}

Запрос 2: индекс = места

{
    "query": {
        "match": {
            "placeName": {
                "query": "welder",
                "fuzziness": 20
            }
        }
    }
}

Может кто-нибудь опубликовать запрос, который при передаче слова сварщик будет возвращать документы с именем сварщика (также должен работать для других терминов как это, это просто пример)

Редактировать 1: Это образец документа места, который я хотел бы вернуть по любому из запросов, опубликованных выше:

{
   cityId: 29,
   placeName: "Welder's Garage Islamabad",
   cityName: "Islamabad",
   status: "verified",
   category: null,
   reviews: []
}

1 Ответ

0 голосов
/ 11 марта 2020

Используя ваше сопоставление, запрос и размытость, установленные как "20", я получаю документ обратно. Нечеткость: 20 будет допускать 20 редактируемое расстояние между искомым словом и словом сварщика, поэтому даже «w» будет соответствовать «сварщику». Я думаю, что это значение отличается в вашем фактическом запросе.

Если вы хотите найти сварщика или сварщиков и вернуть их, тогда вы можете использовать фильтр жетонов стержня

Отображение:

PUT indexfuzzy
{
  "mappings": {
    "properties": {
      "cityId": {
        "type": "integer"
      },
      "cityName": {
        "type": "text"
      },
      "placeName": {
        "type": "text",
        "analyzer": "my_analyzer"
      },
      "status": {
        "type": "keyword"
      },
      "category": {
        "type": "keyword"
      },
      "reviews": {
        "properties": {
          "rating": {
            "type": "long"
          },
          "comment": {
            "type": "keyword"
          },
          "user": {
            "type": "nested"
          }
        }
      }
    }
  },
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "stem_possessive_english",
            "stem_minimal_english"
          ]
        }
      },
      "filter": {
        "stem_possessive_english": {
          "type": "stemmer",
          "name": "possessive_english"
        },
        "stem_minimal_english": {
          "type": "stemmer",
          "name": "minimal_english"
        }
      }
    }
  }
}

Запрос:

GET indexfuzzy/_search
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "placeName": {
                           "query": "welder"--> welder,welders,welder's will work
                        }
                    }
                },
                 {
                    "match": {
                        "cityName": {
                            "query": "welder"
                        }
                    }
                }

            ]
        }
    }
}

Результат:

[
      {
        "_index" : "indexfuzzy",
        "_type" : "_doc",
        "_id" : "Jc-yx3ABd7NBn_0GTBdp",
        "_score" : 0.2876821,
        "_source" : {
          "cityId" : 29,
          "placeName" : "Welder's Garage Islamabad",
          "cityName" : "Islamabad",
          "status" : "verified",
          "category" : null,
          "reviews" : [ ]
        }
      }
    ]

ownive_engli sh: - удаляет трейлинги из токенов minimal_engli sh: - удаляет множественное число

GET <index_name>/_analyze
{
  "text": "Welder's Garage Islamabad",
  "analyzer": "my_analyzer"
}

возвращает

{
  "tokens" : [
    {
      "token" : "welder", --> will be matched for welder's, welders
      "start_offset" : 0,
      "end_offset" : 8,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "garage",
      "start_offset" : 9,
      "end_offset" : 15,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "islamabad",
      "start_offset" : 16,
      "end_offset" : 25,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}
...