Как написать для этого поисковый запрос elasti c? - PullRequest
2 голосов
/ 21 июня 2020

Как написать запрос со следующими условиями:

  1. status НЕ ДОЛЖЕН быть «НЕАКТИВНЫМ»
  2. searchString ДОЛЖЕН быть «some_String»
  3. adsPurchased ДОЛЖЕН быть быть верным
  4. должен иметь «Продукт 1» в разделе productCost
  5. Сортировка по стоимости «Продукта 1»

Структура данных:

"name": "Ross",
  "status": "ACTIVE",
  "adsPurchased": true,
  "searchString": "some_tring",
  "productCost": [
    {
      "product": "Product 1",
      "cost": "50.0"
    },
    {
      "product": "Product 2",
      "cost": "80.0"
    }
  ]
}

{
  "name": "Chandler",
  "status": "INACTIVE",
  "adsPurchased": true,
  "searchString": "some_String",
  "productCost": [
    {
      "product": "Product 1",
      "cost": "60.0"
    },
    {
      "product": "Product 4",
      "cost": "800.0"
    }
  ]
}

{
  "name": "joey",
  "status": "ACTIVE",
  "adsPurchased": true,
  "searchString": "some_tring",
  "productCost": [
    {
      "product": "Product 1",
      "cost": "30.0"
    },
    {
      "product": "Product 5",
      "cost": "90.0"
    }
  ]
}


So, I should get Ross and Joey

Ответы [ 3 ]

1 голос
/ 21 июня 2020

Добавление Рабочий пример с сопоставлением, образцами документов и поисковым запросом.

Сопоставление:

{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "status": {
        "type": "text"
      },
      "adsPurchased": {
        "type": "boolean"
      },
      "searchString": {
        "type": "text"
      },
      "productCost": {
        "type": "nested",
        "properties": {
          "product": {
            "type": "text"
          },
          "cost": {
            "type": "integer"
          }
        }
      }
    }
  }
}

Поисковый запрос:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "adsPurchased": true    -->adsPurchased MUST to be true
          }
        },
        {
          "match": {
            "searchString": "some_tring"    -->searchString MUST be "some_tring"
          }
        },
        {
          "nested": {
            "path": "productCost",
            "query": {
              "bool": {
                "must": [           -->must have "Product 1" under productCost
                  {
                    "match": {
                      "productCost.product": "Product 1"  
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "status": "INACTIVE"    -->status MUST NOT be "INACTIVE"              
            }
        }
      ]
    }
  },
  "sort": [                                 -->Sort them based on cost
    {
      "productCost.cost": {
        "order": "asc",
        "nested_path": "productCost"
      }
    }
  ]
}

Результат поиска:

"hits": [
      {
        "_index": "foo3",
        "_type": "_doc",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "joey",
          "status": "ACTIVE",
          "adsPurchased": true,
          "searchString": "some_tring",
          "productCost": [
            {
              "product": "Product 1",
              "cost": "30.0"
            },
            {
              "product": "Product 5",
              "cost": "90.0"
            }
          ]
        },
        "sort": [
          30
        ]
      },
      {
        "_index": "foo3",
        "_type": "_doc",
        "_id": "1",
        "_score": null,
        "_source": {
          "name": "Ross",
          "status": "ACTIVE",
          "adsPurchased": true,
          "searchString": "some_tring",
          "productCost": [
            {
              "product": "Product 1",
              "cost": "50.0"
            },
            {
              "product": "Product 2",
              "cost": "80.0"
            }
          ]
        },
        "sort": [
          50
        ]
      }
    ]

В результате поиска вы получите желаемый результат, например Росс и Джоуи

Чтобы узнать больше о вложенной сортировке, вы можете обратиться к этой официальной документации , а для вложенных запросов обратитесь к this

0 голосов
/ 21 июня 2020

Вам нужно что-то вроде этого must и must_not внутри filter и sort , я использовал контекст фильтра, потому что он быстрее, вы при необходимости можно использовать контекст запроса. Посмотрите разницу между контекстом запроса и фильтра: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html

GET /your_index_name/_search
{
   "query" : {
      "constant_score" : { 
         "filter" : {
            "bool" : {
              "must" : [
                 { "term" : {"searchString" : "some_String"}}, 
                 { "term" : {"adsPurchased" : true}},
                 { "nested":
                      {
                        "path": "parent","query": {
                           "match": {"productCost.cost": "Product 1"}
                         }
                      }
                 }
              ],
              "must_not" : {
                 "term" : {"status" : "INACTIVE"} 
              }
           }
         }
      }
   }, 
    "sort" : [
    {
      "productCost.cost" : {
         "order" : "asc",
         "nested": {
            "path": "productCost"
         }
      }
    }
  ]
}
0 голосов
/ 21 июня 2020

Есть два основных способа сделать это.

  1. Используя запрос типа bool. в этом типе запроса вы можете добавить несколько логических операторов в свой запрос (must, must_not, should), а затем и добавить несколько типов предложений в каждый оператор, что-то вроде этого

  2. Использование queryString . Elasticsearch предоставляет вам способ написать запрос с несколькими запросами с разными предложениями внутри строки

Bool-запрос:

POST _search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "user" : "kimchy" }
      },
      "filter": {
        "term" : { "tag" : "tech" }
      },
      "must_not" : {
        "range" : {
          "age" : { "gte" : 10, "lte" : 20 }
        }
      },
      "should" : [
        { "term" : { "tag" : "wow" } },
        { "term" : { "tag" : "elasticsearch" } }
      ],
      "minimum_should_match" : 1,
      "boost" : 1.0
    }
  }

Строка запроса:

GET /_search
{
    "query": {
        "query_string" : {
            "query" : "field1:value1 AND (field2:value2 or field2:value3) and  value4 and key5:(value6 or value7)",
            "default_field" : "content"
        }
    }
}

Значение 4 будет найдено в поле default_field, указанном ниже

...