[Повернуть] 23 самых полезных навыка поиска Elasticsearch

задняя часть Elasticsearch регулярное выражение Groovy

предисловие

В этой статье в основном представлены 23 наиболее полезных метода поиска Elasticsearch и приведены подробные примеры исходного кода.И с соответствующей реализацией Java API, редкие обучающие и практические материалы по Elasticsearch

подготовка данных

Чтобы объяснить различные типы поиска ES, мы получим набор документов, содержащих следующие типы:

title               标题
authors             作者
summary             摘要
publish_date        发布日期
num_reviews         评论数
publisher           出版社

Во-первых, мы используем массовый API для создания новых индексов и отправки данных пакетами.

# 设置索引 settings
PUT /bookdb_index
{ "settings": { "number_of_shards": 1 }}

# bulk 提交数据
POST /bookdb_index/book/_bulk
{"index":{"_id":1}}
{"title":"Elasticsearch: The Definitive Guide","authors":["clinton gormley","zachary tong"],"summary":"A distibuted real-time search and analytics engine","publish_date":"2015-02-07","num_reviews":20,"publisher":"oreilly"}
{"index":{"_id":2}}
{"title":"Taming Text: How to Find, Organize, and Manipulate It","authors":["grant ingersoll","thomas morton","drew farris"],"summary":"organize text using approaches such as full-text search, proper name recognition, clustering, tagging, information extraction, and summarization","publish_date":"2013-01-24","num_reviews":12,"publisher":"manning"}
{"index":{"_id":3}}
{"title":"Elasticsearch in Action","authors":["radu gheorge","matthew lee hinman","roy russo"],"summary":"build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms","publish_date":"2015-12-03","num_reviews":18,"publisher":"manning"}
{"index":{"_id":4}}
{"title":"Solr in Action","authors":["trey grainger","timothy potter"],"summary":"Comprehensive guide to implementing a scalable search engine using Apache Solr","publish_date":"2014-04-05","num_reviews":23,"publisher":"manning"}

Уведомление: в этом эксперименте использовалась версия ES 6.3.0.

1. Базовый запрос соответствия

1.1 Полнотекстовый поиск

Существует два способа выполнения полнотекстового поиска:

1) Используйте поисковый API, который включает параметры как часть URL-адреса.

Пример. Ниже выполняется полнотекстовый поиск по запросу «guide».

GET bookdb_index/book/_search?q=guide

[Results]
  "hits": {
    "total": 2,
    "max_score": 1.3278645,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1.3278645,
        "_source": {
          "title": "Solr in Action",
          "authors": [
            "trey grainger",
            "timothy potter"
          ],
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "publish_date": "2014-04-05",
          "num_reviews": 23,
          "publisher": "manning"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 1.2871116,
        "_source": {
          "title": "Elasticsearch: The Definitive Guide",
          "authors": [
            "clinton gormley",
            "zachary tong"
          ],
          "summary": "A distibuted real-time search and analytics engine",
          "publish_date": "2015-02-07",
          "num_reviews": 20,
          "publisher": "oreilly"
        }
      }
    ]
  }

2) Используйте полный ES DSL с телом Json в качестве тела запроса.Результат выполнения такой же, как и у метода 1).

GET bookdb_index/book/_search
{
  "query": {
    "multi_match": {
      "query": "guide",
      "fields" : ["_all"]
    }
  }
}

Интерпретация:Используйте ключевое слово multi_match вместо ключевого слова match в качестве удобного сокращения для запуска одного и того же запроса в нескольких полях. Атрибут fields указывает поля для запроса, в этом случае мы хотим запросить все поля в документе.

Примечание. ES 6.x не включен по умолчанию._allПоля, если поля не указаны, поиск по умолчанию выполняется по всем полям

1.2 Укажите конкретное поле для поиска

Оба API также позволяют указать поля для поиска.
Например, для поиска книг со словом «в действии» в поле заголовка

1) Метод получения URL

GET bookdb_index/book/_search?q=title:in action

[Results]
  "hits": {
    "total": 2,
    "max_score": 1.6323128,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 1.6323128,
        "_source": {
          "title": "Elasticsearch in Action",
          "authors": [
            "radu gheorge",
            "matthew lee hinman",
            "roy russo"
          ],
          "summary": "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
          "publish_date": "2015-12-03",
          "num_reviews": 18,
          "publisher": "manning"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1.6323128,
        "_source": {
          "title": "Solr in Action",
          "authors": [
            "trey grainger",
            "timothy potter"
          ],
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "publish_date": "2014-04-05",
          "num_reviews": 23,
          "publisher": "manning"
        }
      }
    ]
  }

2) Метод поиска DSLОднако полный DSL дает вам больше гибкости для создания более сложных запросов (как мы увидим позже) и указания результатов, которые вы хотите вернуть. В приведенном ниже примере мы указываем количество возвращаемых результатов, смещение (полезно для разбиения на страницы), поле документа, которое мы хотим вернуть, и выделение атрибута.

Представление числа результата: размер
Представление значения смещения: от
Задает представление возвращаемого поля: _source
Представление подсветки: Highlight

GET bookdb_index/book/_search
{
  "query": {
    "match": {
      "title": "in action"
    }
  },
  "size": 2,
  "from": 0,
  "_source": ["title", "summary", "publish_date"],
  "highlight": {
    "fields": {
      "title": {}
    }
  }
}

[Results]
  "hits": {
    "total": 2,
    "max_score": 1.6323128,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 1.6323128,
        "_source": {
          "summary": "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        },
        "highlight": {
          "title": [
            "Elasticsearch <em>in</em> <em>Action</em>"
          ]
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1.6323128,
        "_source": {
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        },
        "highlight": {
          "title": [
            "Solr <em>in</em> <em>Action</em>"
          ]
        }
      }
    ]
  }

Уведомление:

  1. заmulti-wordЗапросы поиска и сопоставления позволяют указать, следует ли использовать оператор и, вместо использования оператора по умолчанию или ---> "оператор" : "и"
  2. Вы также можете указатьminimum_should_matchПараметры для настройки релевантности возвращаемых результатов, подробности можно получить, запросив руководство Elasticsearch в руководстве Elasticsearch.

2. Поиск по нескольким полям

Как мы уже видели, для запроса нескольких полей документа в поиске (например, для поиска одной и той же строки запроса в заголовке и аннотации) используйте запрос multi_match.

GET bookdb_index/book/_search
{
  "query": {
    "multi_match": {
      "query": "guide", 
      "fields": ["title", "summary"]
    }
  }
}

[Results]
  "hits": {
    "total": 3,
    "max_score": 2.0281231,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 2.0281231,
        "_source": {
          "title": "Elasticsearch: The Definitive Guide",
          "authors": [
            "clinton gormley",
            "zachary tong"
          ],
          "summary": "A distibuted real-time search and analytics engine",
          "publish_date": "2015-02-07",
          "num_reviews": 20,
          "publisher": "oreilly"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1.3278645,
        "_source": {
          "title": "Solr in Action",
          "authors": [
            "trey grainger",
            "timothy potter"
          ],
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "publish_date": "2014-04-05",
          "num_reviews": 23,
          "publisher": "manning"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 1.0333893,
        "_source": {
          "title": "Elasticsearch in Action",
          "authors": [
            "radu gheorge",
            "matthew lee hinman",
            "roy russo"
          ],
          "summary": "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
          "publish_date": "2015-12-03",
          "num_reviews": 18,
          "publisher": "manning"
        }
      }
    ]
  }

Примечание. Причина, по которой документ 4 (_id=4) соответствует приведенным выше результатам, заключается в том, что руководство существует в сводке.

3. Повышение улучшает получение результатов поля (Повышение)

Поскольку мы ищем по нескольким полям, мы можем захотеть улучшить оценку для поля. В приведенном ниже примере мы увеличили оценку поля «Сводка» в 3 раза, чтобы повысить важность поля «Сводка», тем самым повысив релевантность документа 4.

GET bookdb_index/book/_search
{
  "query": {
    "multi_match": {
      "query": "elasticsearch guide", 
      "fields": ["title", "summary^3"]
    }
  },
  "_source": ["title", "summary", "publish_date"]
}

[Results]
  "hits": {
    "total": 3,
    "max_score": 3.9835935,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 3.9835935,
        "_source": {
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 3.1001682,
        "_source": {
          "summary": "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 2.0281231,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      }
    ]
  }

Примечание. Повышение означает не просто вычисление умножения баллов для увеличения коэффициентов. Фактическое значение оценки повышения достигается за счет нормализации и некоторой внутренней оптимизации. Дополнительные сведения см. в руководстве по Elasticsearch.

4. Логический запрос (логический запрос)

Наши поисковые запросы можно точно настроить с помощью операторов И/ИЛИ/НЕ, чтобы предоставить более релевантные или конкретные результаты поиска.

В API поиска это делается с помощью логического запроса. Логический запрос принимает параметр must (эквивалентно AND), параметр must_not (эквивалентно NOT) или параметр must (эквивалентно OR).

Например, если я хочу найти книгу под названием «Elasticsearch» или «Solr» в названии И по «clinton gormley», но НЕ по «radu gheorge»,

GET bookdb_index/book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {"match": {"title": "Elasticsearch"}},
              {"match": {"title": "Solr"}}
            ]
          }
        },
        {
          "match": {"authors": "clinton gormely"}
        }
      ],
      "must_not": [
        {
          "match": {"authors": "radu gheorge"}
        }
      ]
    }
  }
}

[Results]
  "hits": {
    "total": 1,
    "max_score": 2.0749094,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 2.0749094,
        "_source": {
          "title": "Elasticsearch: The Definitive Guide",
          "authors": [
            "clinton gormley",
            "zachary tong"
          ],
          "summary": "A distibuted real-time search and analytics engine",
          "publish_date": "2015-02-07",
          "num_reviews": 20,
          "publisher": "oreilly"
        }
      }
    ]
  }

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

  • Когда есть необходимость на том же уровне, что и должна, условия в должны быть выполнены или нет.Чем больше выполнено, тем выше оценка.
  • Когда must не указан, хотя бы одно из условий должно быть выполнено по умолчанию.

Примечание. Как видите, логический запрос может содержать любой другой тип запроса, включая другие логические запросы, для создания произвольно сложных или глубоко вложенных запросов.

5. Нечеткие запросы

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

GET bookdb_index/book/_search
{
  "query": {
    "multi_match": {
      "query": "comprihensiv guide",
      "fields": ["title","summary"],
      "fuzziness": "AUTO"
    }
  },
  "_source": ["title","summary","publish_date"],
  "size": 2
}

[Results]
  "hits": {
    "total": 2,
    "max_score": 2.4344182,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 2.4344182,
        "_source": {
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 1.2871116,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      }
    ]
  }

Неоднозначное значение "AUTO" эквивалентно указанию значения 2, когда длина поля больше 5. Однако установка расстояния редактирования 1 для 80 % ошибок и 1 для двусмысленности может улучшить общую производительность поиска. Чтобы получить больше информации,Typos and Misspellingsch

6. Поиск подстановочных знаков в запросе подстановочных знаков

Запросы с подстановочными знаками позволяют указывать совпадающие шаблоны вместо целых терминов для поиска.

  • ? соответствует любому символу
    • соответствует нулю или более символов

Например, чтобы найти все записи с авторами, начинающимися на букву «т», следующим образом

GET bookdb_index/book/_search
{
  "query": {
    "wildcard": {
      "authors": {
        "value": "t*"
      }
    }
  },
  "_source": ["title", "authors"],
  "highlight": {
    "fields": {
      "authors": {}
    }
  }
}

[Results]
  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 1,
        "_source": {
          "title": "Elasticsearch: The Definitive Guide",
          "authors": [
            "clinton gormley",
            "zachary tong"
          ]
        },
        "highlight": {
          "authors": [
            "zachary <em>tong</em>"
          ]
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "2",
        "_score": 1,
        "_source": {
          "title": "Taming Text: How to Find, Organize, and Manipulate It",
          "authors": [
            "grant ingersoll",
            "thomas morton",
            "drew farris"
          ]
        },
        "highlight": {
          "authors": [
            "<em>thomas</em> morton"
          ]
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1,
        "_source": {
          "title": "Solr in Action",
          "authors": [
            "trey grainger",
            "timothy potter"
          ]
        },
        "highlight": {
          "authors": [
            "<em>trey</em> grainger",
            "<em>timothy</em> potter"
          ]
        }
      }
    ]
  }

7. Извлечение регулярных выражений (Regexp Query)

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

POST bookdb_index/book/_search
{
  "query": {
    "regexp": {
      "authors": "t[a-z]*y"
    }
  },
  "_source": ["title", "authors"],
  "highlight": {
    "fields": {
      "authors": {}
    }
  }
}

[Results]
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1,
        "_source": {
          "title": "Solr in Action",
          "authors": [
            "trey grainger",
            "timothy potter"
          ]
        },
        "highlight": {
          "authors": [
            "<em>trey</em> grainger",
            "<em>timothy</em> potter"
          ]
        }
      }
    ]
  }

8. Соответствие фразовому запросу

Запросы на совпадение фраз требуют, чтобы все слова в строке запроса присутствовали в документе в соответствии со строкой запроса.указанный порядокиблизко друг к другу.

По умолчанию слова должны быть точно смежными, но вы можете указать значение наклона, которое указывает, насколько далеко от слова к слову, при этом учитывая соответствие документов.

GET bookdb_index/book/_search
{
  "query": {
    "multi_match": {
      "query": "search engine",
      "fields": ["title", "summary"],
      "type": "phrase",
      "slop": 3
    }
  },
  "_source": [ "title", "summary", "publish_date" ]
}

[Results]
  "hits": {
    "total": 2,
    "max_score": 0.88067603,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 0.88067603,
        "_source": {
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 0.51429313,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      }
    ]
  }

Примечание. В приведенном выше примере document_id 1 обычно имеет более высокий балл для запросов нефразового типа и появляется перед document_id 4 из-за меньшей длины поля.

Однако в качестве фразового запроса учитывается близость слова к слову, поэтому оценка document_id 4 лучше.

9. Поиск префикса совпадающей фразы

Запросы Match Phrase Prefix обеспечивают мгновенный тип или «относительно простые» версии поиска с автозаполнением во время запроса без какой-либо подготовки данных.

Как и запрос match_phrase, он принимает параметр наклона, что делает порядок и относительное положение слов менее «строгими». Он также принимает параметр max_expansions, чтобы ограничить количество совпадающих условий для снижения ресурсоемкости.

GET bookdb_index/book/_search
{
  "query": {
    "match_phrase_prefix": {
      "summary": {
        "query": "search en",
        "slop": 3,
        "max_expansions": 10
      }
    }
  },
  "_source": ["title","summary","publish_date"]
}

Примечание. Типы поиска во время запроса влияют на производительность. Лучшим решением является использование времени в качестве типа индекса. Для более связанных запросов API Completion Suggester API или фильтры Edge-Ngram .

10. Поиск строки (строка запроса)

Запрос query_string предоставляет способ выполнения запросов multi_match, логических запросов, повышения, нечеткого сопоставления, подстановочных знаков, регулярного выражения регулярного выражения и запросов диапазона в кратком сокращенном синтаксисе.

В приведенном ниже примере мы выполняем нечеткий поиск по слову «алгоритм поиска», одним из авторов которого является «грант ингерсолл» или «том мортон». Мы ищем по всем полям, но применяем усиление к полю сводки документа 2.

GET bookdb_index/book/_search
{
  "query": {
    "query_string": {
      "query": "(saerch~1 algorithm~1) AND (grant ingersoll)  OR (tom morton)",
      "fields": ["summary^2","title","authors","publisher"]
    }
  },
  "_source": ["title","summary","authors"],
  "highlight": {
    "fields": {
      "summary": {}
    }
  }
}

[Results]
  "hits": {
    "total": 1,
    "max_score": 3.571021,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "2",
        "_score": 3.571021,
        "_source": {
          "summary": "organize text using approaches such as full-text search, proper name recognition, clustering, tagging, information extraction, and summarization",
          "title": "Taming Text: How to Find, Organize, and Manipulate It",
          "authors": [
            "grant ingersoll",
            "thomas morton",
            "drew farris"
          ]
        },
        "highlight": {
          "summary": [
            "organize text using approaches such as full-text <em>search</em>, proper name recognition, clustering, tagging"
          ]
        }
      }
    ]
  }

11. Простая строка запроса

Запрос simple_query_string — это версия запроса query_string, которая больше подходит для одного окна поиска, доступного пользователю. потому что он использует+ / | / -замененыAND / OR / NOTи отбросить недопустимую часть запроса вместо создания исключения, если пользователь совершит ошибку.

GET bookdb_index/book/_search
{
  "query": {
    "simple_query_string": {
      "query": "(saerch~1 algorithm~1) + (grant ingersoll)  | (tom morton)",
      "fields": ["summary^2","title","authors","publisher"]
    }
  },
  "_source": ["title","summary","authors"],
  "highlight": {
    "fields": {
      "summary": {}
    }
  }
}

[Results]
# 结果同上

12. Поиск терминов/терминов (поиск по заданному полю)

Примеры в подразделах 1-11 выше являются примерами полнотекстового поиска. Иногда нас больше интересуют структурированные поиски, когда мы хотим найти точные совпадения и вернуть результаты.

В приведенном ниже примере мы ищем все книги в индексе, опубликованном Manning Publications (с помощью запроса терминов и терминов).

GET bookdb_index/book/_search
{
  "query": {
    "term": {
      "publisher": {
        "value": "manning"
      }
    }
  },
  "_source" : ["title","publish_date","publisher"]
}

[Results]
  "hits": {
    "total": 3,
    "max_score": 0.35667494,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "2",
        "_score": 0.35667494,
        "_source": {
          "publisher": "manning",
          "title": "Taming Text: How to Find, Organize, and Manipulate It",
          "publish_date": "2013-01-24"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 0.35667494,
        "_source": {
          "publisher": "manning",
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 0.35667494,
        "_source": {
          "publisher": "manning",
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        }
      }
    ]
  }

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

GET bookdb_index/book/_search
{
  "query": {
    "terms": {
      "publisher": ["oreilly", "manning"]
    }
  }
}

13. Запрос терминов — отсортировано

Запросы терминов, как и другие запросы, можно легко сортировать. Также допускается многоуровневая сортировка

GET bookdb_index/book/_search
{
  "query": {
    "term": {
      "publisher": {
        "value": "manning"
      }
    }
  },
  "_source" : ["title","publish_date","publisher"],
  "sort": [{"publisher.keyword": { "order": "desc"}},
    {"title.keyword": {"order": "asc"}}]
}

[Results]
  "hits": {
    "total": 3,
    "max_score": null,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": null,
        "_source": {
          "publisher": "manning",
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        },
        "sort": [
          "manning",
          "Elasticsearch in Action"
        ]
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": null,
        "_source": {
          "publisher": "manning",
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        },
        "sort": [
          "manning",
          "Solr in Action"
        ]
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "2",
        "_score": null,
        "_source": {
          "publisher": "manning",
          "title": "Taming Text: How to Find, Organize, and Manipulate It",
          "publish_date": "2013-01-24"
        },
        "sort": [
          "manning",
          "Taming Text: How to Find, Organize, and Manipulate It"
        ]
      }
    ]
  }

Примечание. Elasticsearch 6.x использует поля текстового типа для полнотекстового поиска и не использует поля текстового типа для сортировки.

14. Запрос диапазона

Еще одним примером структурированного поиска является поиск по диапазону. В приведенном ниже примере мы ищем книги, опубликованные в 2015 году.

GET bookdb_index/book/_search
{
  "query": {
    "range": {
      "publish_date": {
        "gte": "2015-01-01",
        "lte": "2015-12-31"
      }
    }
  },
  "_source" : ["title","publish_date","publisher"]
}

[Results]
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 1,
        "_source": {
          "publisher": "oreilly",
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 1,
        "_source": {
          "publisher": "manning",
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        }
      }
    ]
  }

Примечание. Запросы диапазона доступны для полей даты, числа и строкового типа.

15. Отфильтрованный запрос

(больше не существует с версии 5.0, не обращайте внимания)

Фильтрованные запросы позволяют фильтровать результаты запроса. В приведенном ниже примере мы запрашиваем книгу с названием «Elasticsearch» в заголовке или аннотации, но хотим отфильтровать результаты только для тех, у кого есть 20 или более отзывов.

POST /bookdb_index/book/_search
{
    "query": {
        "filtered": {
            "query" : {
                "multi_match": {
                    "query": "elasticsearch",
                    "fields": ["title","summary"]
                }
            },
            "filter": {
                "range" : {
                    "num_reviews": {
                        "gte": 20
                    }
                }
            }
        }
    },
    "_source" : ["title","summary","publisher", "num_reviews"]
}


[Results]
"hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 0.5955761,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "publisher": "oreilly",
          "num_reviews": 20,
          "title": "Elasticsearch: The Definitive Guide"
        }
      }
    ]

Примечание. Отфильтрованные запросы не требуют наличия запроса для фильтрации. Если запрос не указан, выполняется запрос match_all, который в основном возвращает все документы в индексе, которые затем фильтруются. На самом деле фильтр запускается первым, уменьшая площадь обрабатываемой поверхности. Кроме того, фильтр кэшируется после первого использования, что делает его очень эффективным.

обновить:Отфильтрованные запросы были удалены с выпуском Elasticsearch 5.X в пользу логических запросов. Это тот же пример, что и переписанный выше запрос с использованием bool. Возвращаемый результат точно такой же.

GET bookdb_index/book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "elasticsearch",
            "fields": ["title","summary"]
          }
        }
      ],
      "filter": {
        "range": {
          "num_reviews": {
            "gte": 20
          }
        }
      }
    }
  },
  "_source" : ["title","summary","publisher", "num_reviews"]
}

16. Несколько фильтров (несколько фильтров)

(5.x больше не поддерживается, не надо обращать внимание) Несколько фильтров можно комбинировать с помощью логических фильтров.

В следующем примере фильтр определяет, что возвращаемые результаты должны содержать не менее 20 комментариев, не должны публиковаться до 2015 года и должны быть опубликованы oreilly.

POST /bookdb_index/book/_search
{
    "query": {
        "filtered": {
            "query" : {
                "multi_match": {
                    "query": "elasticsearch",
                    "fields": ["title","summary"]
                }
            },
            "filter": {
                "bool": {
                    "must": {
                        "range" : { "num_reviews": { "gte": 20 } }
                    },
                    "must_not": {
                        "range" : { "publish_date": { "lte": "2014-12-31" } }
                    },
                    "should": {
                        "term": { "publisher": "oreilly" }
                    }
                }
            }
        }
    },
    "_source" : ["title","summary","publisher", "num_reviews", "publish_date"]
}


[Results]
"hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 0.5955761,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "publisher": "oreilly",
          "num_reviews": 20,
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      }
    ]

17. Оценка функции: фактор значения поля

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

В нашем случае мы хотим добавить больше популярных книг (судя по количеству отзывов). Это можно оценить с помощью функции field_value_factor.

GET bookdb_index/book/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "search engine",
          "fields": ["title","summary"]
        }
      },
      "field_value_factor": {
        "field": "num_reviews",
        "modifier": "log1p",
        "factor": 2
      }
    }
  },
  "_source": ["title", "summary", "publish_date", "num_reviews"]
}

[Results]
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 1.5694137,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "num_reviews": 20,
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 1.4725765,
        "_source": {
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "num_reviews": 23,
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 0.14181662,
        "_source": {
          "summary": "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
          "num_reviews": 18,
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "2",
        "_score": 0.13297246,
        "_source": {
          "summary": "organize text using approaches such as full-text search, proper name recognition, clustering, tagging, information extraction, and summarization",
          "num_reviews": 12,
          "title": "Taming Text: How to Find, Organize, and Manipulate It",
          "publish_date": "2013-01-24"
        }
      }
    ]
  }

Примечание 1: мы могли бы запустить обычный запрос multi_match и отсортировать по полю num_reviews, но мы потеряли бы преимущество оценки релевантности.
Заметка 2: существует множество дополнительных параметров, которые можно настроить для исходной оценки корреляции. Степень эффекта повышения (например, «модификатор», «фактор», «режим усиления» и т. д.).
Подробнее см. в руководстве по Elasticsearch.

18. Оценка функции: функции распада

Предположим, мы не хотим постепенно увеличивать оценку на значение поля, чтобы получить желаемый результат. Примеры: диапазон цен, диапазон числовых полей, диапазон дат. В нашем случае мы ищем книги по «поисковикам», опубликованные примерно в июне 2014 года.

GET bookdb_index/book/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "search engine",
          "fields": ["title", "summary"]
        }
      },
      "functions": [
        {
          "exp": {
            "publish_date": {
              "origin": "2014-06-15",
              "scale": "30d",
              "offset": "7d"
            }
          }
        }
      ],
      "boost_mode": "replace"
    }
  },
  "_source": ["title", "summary", "publish_date", "num_reviews"]
}

[Results]
  "hits": {
    "total": 4,
    "max_score": 0.22793062,
    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 0.22793062,
        "_source": {
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "num_reviews": 23,
          "title": "Solr in Action",
          "publish_date": "2014-04-05"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 0.0049215667,
        "_source": {
          "summary": "A distibuted real-time search and analytics engine",
          "num_reviews": 20,
          "title": "Elasticsearch: The Definitive Guide",
          "publish_date": "2015-02-07"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "2",
        "_score": 0.000009612435,
        "_source": {
          "summary": "organize text using approaches such as full-text search, proper name recognition, clustering, tagging, information extraction, and summarization",
          "num_reviews": 12,
          "title": "Taming Text: How to Find, Organize, and Manipulate It",
          "publish_date": "2013-01-24"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "3",
        "_score": 0.0000049185574,
        "_source": {
          "summary": "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
          "num_reviews": 18,
          "title": "Elasticsearch in Action",
          "publish_date": "2015-12-03"
        }
      }
    ]
  }

19. Оценка функции: оценка сценария

При необходимости укажите сценарий Groovy для оценки, если встроенная функция оценки не соответствует вашим потребностям.

В нашем примере мы хотим указать сценарий, который учитывает publish_date, а затем решает, сколько комментариев следует учитывать. У новых книг может быть не так много отзывов, поэтому они не должны «платить» за это.

Сценарий оценки выглядит следующим образом:

publish_date = doc['publish_date'].value
num_reviews = doc['num_reviews'].value

if (publish_date > Date.parse('yyyy-MM-dd', threshold).getTime()) {
  my_score = Math.log(2.5 + num_reviews)
} else {
  my_score = Math.log(1 + num_reviews)
}
return my_score

Для динамического использования сценария подсчета очков мы используем параметр script_score.

GET /bookdb_index/book/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "search engine",
          "fields": ["title","summary"]
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
              "params": {
                "threshold": "2015-07-30"
              },  
              "lang": "groovy", 
              "source": "publish_date = doc['publish_date'].value; num_reviews = doc['num_reviews'].value; if (publish_date > Date.parse('yyyy-MM-dd', threshold).getTime()) { return log(2.5 + num_reviews) }; return log(1 + num_reviews);"
            }
          }
        }
      ]
    }
  },
  "_source": ["title","summary","publish_date", "num_reviews"]
}

Примечание 1: чтобы использовать динамические скрипты, их необходимо включить для экземпляра Elasticsearch в файле config/elasticsearch.yml. Также можно использовать скрипты, уже хранящиеся на сервере Elasticsearch. Ознакомьтесь со справочными документами Elasticsearch для получения дополнительной информации.
Заметка 2:JSON не может содержать встроенные символы новой строки, поэтому для разделения инструкций используются точки с запятой.
Первоначальный автор: Тим Оджо 05, 16 августа · Зона больших данных
Оригинальный адрес:D zone.com/articles/23…

Примечание. Как ES6.3 включает groovy-скрипты? Конфигурация не удалась
script.allowed_types: inline & script.allowed_contexts: search, update

Реализация API Java

API Java реализует указанный выше запрос, см. кодGitHub.com/whirly is/голодный…

Справочная статья:
Мир Минъи:23 самых полезных совета по поиску Elasticseaerch, которые вы должны знать
Английский оригинал:23 Useful Elasticsearch Example Queries


Для получения дополнительной информации, пожалуйста, посетите мой личный блог:laijianfeng.org

Откройте WeChat и просканируйте, подпишитесь на общедоступную учетную запись [Xiao Xuanfeng] WeChat и вовремя получайте сообщения в блогах.

小旋锋的微信公众号