ElasticsearchのMUST（AND）,SHOULD（OR）,MUST_NOTについて

「must_not [A,B,]」はSQLでいう「NOT (A AND B)」なのか「NOT (A OR B)」なのか…動作確認した。
（2023/10/19㈭にbid:7815のハンドボール掲示板の所属先カテゴリidを129→118に移動した際、発生したのを機に…。）

tid=21,22,24,24,25の集合があるとき
must_not=>[tid=>22,tid=>24,]
↓
tid=21,23,25が抽出される。
つまり
「NOT (tid=22 OR tid=24)」
と書くのと同じ動作。
「NOT (tid=22 AND tid=24)」
ではない！

must_not=>[tid=>22,!tid=>22,]
↓
NOT(tid=22 OR ! tid=22)
↓
何も抽出されない。◯

NOT(tid=22 AND ! tid=22) ⇔ (NOT tid=22 OR tid=22)
↑
このように全抽出になるわけではない。



注意するのは
must_not 「「性別＝男性」、NOT「身長が170cm以上」（身長が170cm未満）、」
は
「男性かつ170cm未満の人」以外の人、つまり「女性または170cm以上の人」が抽出対象ではなく、
「男性または170cm未満の人」以外の人、つまり「女性かつ170cm以上の人」が抽出対象であること。

ただ、どちらなのか紛らわしいから積極的に書くのは辞めましょう。（苦肉の策レベルとして共有します。）


## 例題として
「カテゴリid129以外で」をベースに→「（カテゴリid129かつbid7815以外）以外で」つまり「カテゴリid129以外またはbid7815で」にしたいとき

👇コレをベースに改修

```
					/*
					"must_not" => [
						[
							"term" => [
								$ctgid_index => 129,
							],
						],
					],
					*/
```
👇コレだと『「カテゴリid129またはbid7815以外」以外』＝「カテゴリid129以外かつbid7815」になってしまう。『「カテゴリid129かつbid7815以外」以外』＝「カテゴリid129以外またはbid7815」になるわけではない。（NG例です。）

```
					"must_not" => [
						[
							"term" => [
								$ctgid_index => 129,
							],
						],
						[
							"bool" => [
								"must_not" => [
									[
										"term" => [
											"bid" => 7815,
										],
									],
								],
							],
						],
					],
```

👇こうするしか思いつかなかった。「カテゴリid129以外またはbid7815」となる。「または」の部分を"should"で接続した。

```
					"should" => [
						[
							"bool" => [
								"must_not" => [
									[
										"term" => [
											$ctgid_index => 129,
										],
									],
								],
							],
						],
						[
							"bool" => [
								"must" => [
									[
										"term" => [
											"bid" => 7815,
										],
									],
								],
							],
						],
					],
					"minimum_should_match" => 1,//👆のカッコのうち1個にマッチしたら…

```



| デジタル回路 | SQL |Elasticsearch |動作 |補足 |
| :-----------: | :-----------: | :-----------: | :-----------: | :-----------: |
| AND回路 | (A and B and C)  | 'must'=>[A,B,C,], |入力/ABCすべてが1のとき1を出力  | － |
| OR回路 | (A or B or C)  |  'should'=>[A,B,C,], | 入力/ABCいずれかが1のとき1を出力  | － |
| NOT回路 | NOT/!  | － | 入力値を反転させて出力  | ESでは「must_not」で代用する |
| NAND回路 | NOT (A and B and C)  | －  | 入力/ABCすべてが1のとき0を出力 | ESでは『"must"の結果を"must_not"で反転する』で代用する |
| NOR回路  | NOT (A or B or C)  | 'must_not'=>[A,B,C,], | 入力/ABCいずれかが1のとき0を出力  | 『'must'の反転』ではなく『'should'の反転』。紛らわしい…(´・ω・｀) |

NAND（NOT AND）の式

```
NOT (A AND B AND C) ⇔ ! (A AND B AND C) ⇔ (!A OR !B OR !C) ⇔ (NOT A OR NOT B OR NOT C)
```

NOR（NOT OR）の式


```
NOT (A OR B OR C) ⇔ ! (A OR B OR C) ⇔ (!A AND !B AND !C) ⇔ (NOT A AND NOT B AND NOT C)
```

※クエリが実行されると、AND で結合された句が最初に評価され、次に OR で結合された句が評価されます。 NOT 演算子は AND と OR のいずれよりも優先されます。

参考にしたURL
LuceneのBooleanQueryについて
https://qiita.com/kincolletech/items/1374d4413036433477a5
Elasticsearchのbool queryを利用してAND OR NOTを書いてみる
https://qiita.com/vanhuyz/items/04a6871ae5f53ba5a97f
デジタル回路の「基本論理回路」まずはコレだけ！回路記号・真理値表も整理
https://engineer-education.com/digital-circuit_logic-circuit/
ドモルガンの法則の解説
https://manabitimes.jp/math/897
抽出条件ペインで検索条件を組み合わせる場合の規則
https://learn.microsoft.com/ja-jp/sql/ssms/visual-db-tools/conventions-combine-search-conditions-in-criteria-pane-visual-db-tools?view=sql-server-ver16