[elasticsearch] elasticsearch bool 쿼리는 OR과 결합해야합니다

현재 solr 기반 응용 프로그램을 elasticsearch로 마이그레이션하려고합니다.

이 lucene 쿼리가 있습니다

((
    name:(+foo +bar)
    OR info:(+foo +bar)
)) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)

내가 이해하는 한 이것은 부울 OR과 결합 된 MUST 절의 조합입니다.

“(이름에 foo AND bar) 또는 (info에 foo AND bar)를 포함하는 모든 문서를 가져 오십시오. 그 후 조건 state = 1로 결과를 필터링하고 이미지가있는 문서를 강화하십시오.”

MUST와 함께 부울 쿼리를 사용하려고했지만 부울 OR을 must 절에 가져 오는 데 실패했습니다. 여기 내가 가진 것입니다 :

GET /test/object/_search
{
  "from": 0,
  "size": 20,
  "sort": {
    "_score": "desc"
  },
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "foo"
          }
        },
        {
          "match": {
            "name": "bar"
          }
        }
      ],
      "must_not": [],
      "should": [
        {
          "match": {
            "has_image": {
              "query": 1,
              "boost": 100
            }
          }
        }
      ]
    }
  }
}

보시다시피 “info”에 대한 조건이 없어야합니다.

누구든지 해결책이 있습니까?

정말 고맙습니다.

** 업데이트 **

elasticsearch 쿼리를 업데이트하고 해당 기능 점수를 제거했습니다. 내 기본 문제는 여전히 존재합니다.



답변

  • 또는 철자
  • AND 는 철자가 필요 합니다
  • NOR의 철자가 되어야합니다.

예:

모든 항목 (둥근 AND (빨간색 또는 파란색))을 보려고합니다.

{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {"shape": "round"}
                },
                {
                    "bool": {
                        "should": [
                            {"term": {"color": "red"}},
                            {"term": {"color": "blue"}}
                        ]
                    }
                }
            ]
        }
    }
}

보다 복잡한 OR 버전을 수행 할 수도 있습니다. 예를 들어 5 개 중 3 개 이상을 일치 시키려면 “should”에서 5 개의 옵션을 지정하고 “minimum_should”를 3으로 설정할 수 있습니다.

내 둥지가 그리 멀지 않은 곳을 찾은 Glen Thompson과 Sebastialonso에게 감사드립니다.

ElasticSearch 6에서 “term”이 “match”가된다고 지적한 Fatmajk에게도 감사드립니다.


답변

마침내 내가 원하는 것을 정확하게 수행하는 쿼리를 만들었습니다.

필터링 된 중첩 부울 쿼리입니다. 왜 이것이 문서화되어 있지 않은지 잘 모르겠습니다. 여기 누군가 말해 줄 수 있을까요?

다음은 쿼리입니다.

GET /test/object/_search
{
  "from": 0,
  "size": 20,
  "sort": {
    "_score": "desc"
  },
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "state": 1
              }
            }
          ]
        }
      },
      "query": {
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "match": {
                      "name": "foo"
                    }
                  },
                  {
                    "match": {
                      "name": "bar"
                    }
                  }
                ],
                "should": [
                  {
                    "match": {
                      "has_image": {
                        "query": 1,
                        "boost": 100
                      }
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "match": {
                      "info": "foo"
                    }
                  },
                  {
                    "match": {
                      "info": "bar"
                    }
                  }
                ],
                "should": [
                  {
                    "match": {
                      "has_image": {
                        "query": 1,
                        "boost": 100
                      }
                    }
                  }
                ]
              }
            }
          ],
          "minimum_should_match": 1
        }
      }
    }
  }
}

의사 SQL에서 :

SELECT * FROM /test/object
WHERE
    ((name=foo AND name=bar) OR (info=foo AND info=bar))
AND state=1

이는 문서 필드 분석 및 name = foo가 내부적으로 처리되는 방식에 따라 달라집니다. 이는 퍼지에서 엄격한 동작까지 다양합니다.

“minimum_should_match”: 1에 따르면, should 문 중 하나 이상이 true 여야합니다.

이 문장은 결과 집합에 has_image : 1을 포함하는 문서가있을 때마다 요소 100만큼 증가한다는 것을 의미합니다. 결과 순서가 변경됩니다.

"should": [
  {
    "match": {
      "has_image": {
        "query": 1,
        "boost": 100
      }
    }
   }
 ]

재밌게 놀아 🙂


답변

Kibana를 사용하여 하나의 외부 부울 쿼리에 여러 부울 쿼리를 중첩시키는 방법입니다.

부울 은 우리가 부울을 사용하고 있음을 나타냅니다

AND를 위한 것이 어야한다

SHOULD을 위한 OR

GET my_inedx/my_type/_search
{
    "query" : {
       "bool": {             //bool indicates we are using boolean operator
            "must" : [       //must is for **AND**
                 {
                   "match" : {
                         "description" : "some text"
                     }
                 },
                 {
                    "match" :{
                          "type" : "some Type"
                     }
                 },
                 {
                    "bool" : {          //here its a nested boolean query
                          "should" : [  //should is for **OR**
                                 {
                                   "match" : {
                                       //ur query
                                  }
                                 },
                                 {
                                    "match" : {}
                                 }
                               ]
                          }
                 }
             ]
        }
    }
}

이것이 ES에 쿼리를 중첩시키는 방법입니다

“bool”에는 더 많은 유형이 있습니다.

  1. 필터

  2. must_not


답변

나는 최근 에이 문제를 해결해야했고 많은 시행 착오 후에 이것을 (PHP에서는 DSL에 직접 매핑) 만들었습니다.

'query' => [
    'bool' => [
        'should' => [
            ['prefix' => ['name_first' => $query]],
            ['prefix' => ['name_last' => $query]],
            ['prefix' => ['phone' => $query]],
            ['prefix' => ['email' => $query]],
            [
                'multi_match' => [
                    'query' => $query,
                    'type' => 'cross_fields',
                    'operator' => 'and',
                    'fields' => ['name_first', 'name_last']
                ]
            ]
        ],
        'minimum_should_match' => 1,
        'filter' => [
            ['term' => ['state' => 'active']],
            ['term' => ['company_id' => $companyId]]
        ]
    ]
]

다음은 SQL에서 다음과 같이 매핑됩니다.

SELECT * from <index>
WHERE (
    name_first LIKE '<query>%' OR
    name_last LIKE '<query>%' OR
    phone LIKE  '<query>%' OR
    email LIKE '<query>%'
)
AND state = 'active'
AND company_id = <query>

이 모든 것의 핵심은 minimum_should_match설정입니다. 이것 없이는 filter완전히을 재정의합니다 should.

이것이 누군가를 돕기를 바랍니다!


답변

$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);

에서 must당신은 당신이 작업 할 쿼리 조건 배열 추가해야 AND하고의를 should당신은 당신이 작업 할 쿼리 조건을 추가해야합니다 OR.

이것을 확인할 수 있습니다 : https://github.com/Smile-SA/elasticsuite/issues/972


답변

Solr의 기본 또는 Lucene 쿼리 파서를 사용하는 경우 거의 항상 쿼리 문자열 쿼리에 넣을 수 있습니다.

POST test/_search
{
  "query": {
    "query_string": {
      "query": "(( name:(+foo +bar) OR info:(+foo +bar)  )) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)"
    }
  }
}

즉, 이미 게시 한 것과 같은 부울 쿼리 를 사용 하거나 두 가지를 조합하여 사용할 수 있습니다.


답변