私のelasticsearchDBには、次のようなドキュメントがあります。
{
"tags" => [
"tag-1",
"tag-2",
"tag-3",
"tag-A"
]
"created_at" =>"2013-07-02 12:42:19 UTC",
"label" =>"Mon super label"
}
次の基準でドキュメントをフィルタリングできるようにしたいと思います。ドキュメントタグ配列にはtags-1、tags-3、tags-2が必要ですが、tags-Aは含まれていません。
ブールフィルターを使おうとしましたが、うまくいきません!
これがあなたが望むことを達成しているように見える方法です: http://sense.qbox.io/Gist/4dd806936f12a9668d61ce63f39cb2c28451244
まず、明示的なマッピングを使用してインデックスを作成しました。これを行ったのは、"tags"
プロパティを"index": "not_analyzed"
に設定できるようにするためです。これは、テキストが変更されないことを意味します。これにより、この例のクエリプロセスが簡素化されます。
curl -XPUT "http://localhost:9200/test_index" -d'
{
"mappings": {
"docs" : {
"properties": {
"tags" : {
"type": "string",
"index": "not_analyzed"
},
"label" : {
"type": "string"
}
}
}
}
}'
次に、いくつかのドキュメントを追加します。
curl -XPUT "http://localhost:9200/test_index/docs/1" -d'
{
"tags" : [
"tag-1",
"tag-2",
"tag-3",
"tag-A"
],
"label" : "item 1"
}'
curl -XPUT "http://localhost:9200/test_index/docs/2" -d'
{
"tags" : [
"tag-1",
"tag-2",
"tag-3"
],
"label" : "item 2"
}'
curl -XPUT "http://localhost:9200/test_index/docs/3" -d'
{
"tags" : [
"tag-1",
"tag-2"
],
"label" : "item 3"
}'
次に、次のように、must
フィルターでbool
句とmust_not
句を使用してクエリを実行できます。
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"terms": {
"tags": [
"tag-1",
"tag-2",
"tag-3"
],
"execution" : "and"
}
}
],
"must_not": [
{
"term": {
"tags": "tag-A"
}
}
]
}
}
}
}
}'
これにより、正しい結果が得られます。
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "docs",
"_id": "2",
"_score": 1,
"_source": {
"tags": [
"tag-1",
"tag-2",
"tag-3"
],
"label": "item 2"
}
}
]
}
}
terms
句のmust
フィルターの"execution" : "and"
パラメーターに注意してください。これは、すべての"tags"
が指定されているドキュメントのみが返されることを意味します(1つ以上に一致するドキュメントではありません)。それはあなたが欠けていたものだったかもしれません。オプションの詳細については、 ES docs を参照してください。
ESがインストールされてlocalhost:9200
で実行されている場合、または独自のエンドポイントを提供できる場合は、実行可能な例 ここ を作成しました。