elasticsearch boolクエリはORと組み合わせる必要があります


181

私は現在、solrベースのアプリケーションをelasticsearchに移行しようとしています。

私はこのルセンのクエリを持っています

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

私が理解している限り、これはブール句ORと組み合わせたMUST句の組み合わせです:

「(fooとbarの名前)または(fooとbar in info)を含むすべてのドキュメントを取得します。その後、条件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"のMUST条件がありません。

誰かが解決策を持っていますか?

どうもありがとうございます。

**更新**

elasticsearchクエリを更新し、その関数スコアを削除しました。私の基本的な問題はまだ存在しています。


1
ElasticSearchがここに問い合わせを組み合わせることで良いドキュメントがあります:elastic.co/guide/en/elasticsearch/guide/current/...
Mr.Coffee

回答:


426
  • ORはスペルする必要があります
  • ANDのスペルは必須です
  • NORのスペルはshould_notです

例:

(丸AND(赤OR青))であるすべてのアイテムを表示します。

{
    "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にも感謝します。


2
should上位レベルboolに引き込み、minimum_should_match: 1作品を含めますか?
2017年

18
この例を試すと、戻り[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]ます。これはどういうわけかバージョンに依存していますか?
DanneJ

26
彼らはそのような簡単な例と説明をドキュメントに追加してみませんか?ドキュメントの例は非常に混乱します。
Nikhil Owalekar 2017年

21
6か月後、すべてのElasticドキュメントを読んだので、ブールロジックを実装する方法を完全に理解したのはこれが初めてです。公式文書は私の意見では明確さが欠けています。
Sebastialonso

3
@アミールどのような不正確な点があれば修正できますか?上記のコンテキストでは、デフォルトminimum_shouldは1であり、これをラップすると、bool少なくとも1つの項目が一致する場合はそのグループがtrueになり、一致するものがない場合はfalseになります。この回答を作成する動機は、私がこの種の問題を正確に解決していたことであり、利用可能なドキュメントや、このようなサイトで見つけることができる回答でさえ、せいぜい役に立たないため、かなりしっかりと把握するまで調査を続けました何が起こっていたかの。答えをさらに改善する方法についての建設的な指針を喜んで歓迎します。
Daniel Fackrell、2018年

69

ようやく、自分が望んでいたとおりのクエリを作成することができました。

フィルターされたネストされたブールクエリ。これが文書化されていない理由はわかりません。多分ここの誰かが私に言うことができますか?

これがクエリです:

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ステートメントの少なくとも1つがtrueでなければならないことを示しています。

このステートメントは、has_image:1を含むドキュメントが結果セットに存在する場合は常に、ファクター100によってブーストされることを意味します。これにより、結果の順序が変更されます。

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

楽しい人を持っている:)


28
神聖ながらくた。誰かがより良い解決策を持っていますか?これを投稿していただきありがとうございます。しかし、これはクエリで論理ORを実現するには複雑すぎます。
nackjicholson 2016

thnx、あなたは私の日を救った)
cubbiu 2016年

3
このクエリは不必要に長いだけでなく、非推奨の構文を使用しています。@ daniel-fackrellの回答が受け入れられるべきです。
エリックアルフォード

4
@EricAlford 2015年からのこの回答は、ESの以前のバージョンに基づいています。より良い解決策を提供してください。
ジェシー

1
アイデア:ElasticSearchを引き継ぐ/フォークし、ユーザーフレンドリーな方法で書き直し、シンプルなクエリ言語を追加して、WIN!資金が必要です。私は入る!他に誰 ?
Sliq

16

これは、Kibanaを使用して、1つの外部ブールクエリに複数のブールクエリをネストする方法です。

boolブール値を使用していることを示します

ANDである必要あります

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


あなたの答えは正確です、しかしそれは少し不器用です、あなたが望むならそれはあなたのための小さな提案です-あなたはそれを適切に編集する必要があります。おそらくそれはあなたにこの答えをもっと好きにしてくれます:)良い一日を。
Dhwanil Patel

6

私も最近この問題を解決する必要があり、試行錯誤を繰り返した結果、これを思いつきました(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

これが誰かを助けることを願っています!


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

mustあなたと一緒に仕事をしたいクエリ条件配列を追加する必要があるANDとしてshouldあなたあなたと仕事をしたいクエリ条件を追加する必要がありますOR

これを確認できますhttps : //github.com/Smile-SA/elasticsuite/issues/972


0

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)"
    }
  }
}

とは言っても、既に投稿したクエリのようにブールクエリを使用することも、2つを組み合わせて使用することもできます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.