簡體   English   中英

如何使用嵌套和非嵌套字段查詢 elasticsearch 索引

[英]How to Query elasticsearch index with nested and non nested fields

我有一個具有以下映射的彈性搜索索引:

PUT /student_detail
{
    "mappings" : {
        "properties" : {
            "id" : { "type" : "long" },
            "name" : { "type" : "text" },
            "email" : { "type" : "text" },
            "age" : { "type" : "text" },
            "status" : { "type" : "text" },
            "tests":{ "type" : "nested" }
        }
    }
}

存儲的數據格式如下:

{
  "id": 123,
  "name": "Schwarb",
  "email": "abc@gmail.com",
  "status": "current",
  "age": 14,
  "tests": [
    {
      "test_id": 587,
      "test_score": 10
    },
    {
      "test_id": 588,
      "test_score": 6
    }
  ]
}

我希望能夠查詢學生的名字像'%warb%'和email像'%gmail.com%'並且ID為587的測試得分> 5等。需要的高水平可以像這樣下面,不知道實際的查詢是什么,為下面這個混亂的查詢道歉

GET developer_search/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "abc"
          }
        },
        {
          "nested": {
            "path": "tests",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "tests.test_id": IN [587]
                    }
                  },
                   {
                    "term": {
                      "tests.test_score": >= some value
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

查詢必須靈活,以便我們可以輸入動態測試 ID 及其各自的分數過濾器以及嵌套字段之外的字段,例如年齡、姓名、狀態

類似的東西?

GET student_detail/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "wildcard": {
            "name": {
              "value": "*warb*"
            }
          }
        },
        {
          "wildcard": {
            "email": {
              "value": "*gmail.com*"
            }
          }
        },
        {
          "nested": {
            "path": "tests",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "tests.test_id": 587
                    }
                  },
                  {
                    "range": {
                      "tests.test_score": {
                        "gte": 5
                      }
                    }
                  }
                ]
              }
            },
            "inner_hits": {}
          }
        }
      ]
    }
  }
}

內部打擊是您正在尋找的。

您必須使用Ngram Tokenizer ,因為出於性能原因,不得使用通配符搜索,我不建議使用它。

將您的映射更改為下面,您可以在下面的映射中創建您自己的分析器

elasticsearch(albiet lucene)如何索引語句是,首先它將語句或段落分解為單詞或標記,然后在該特定字段的倒排索引中索引這些單詞。 此過程稱為分析,僅適用於text數據類型。

因此,現在您只有在這些標記在倒排索引中可用時才能獲得文檔。

默認情況下,將應用標准分析器 我所做的是創建了自己的分析器並使用了 Ngram Tokenizer,它可以創建更多的標記,而不僅僅是單詞。

Life is beautiful默認分析儀將是lifeisbeautiful

但是使用 Ngrams, Life的標記將是lififelife

映射:

PUT student_detail
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 4,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  },
    "mappings" : {
        "properties" : {
            "id" : { 
              "type" : "long" 
            },
            "name" : { 
              "type" : "text",
              "analyzer": "my_analyzer",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            },
            "email" : { 
              "type" : "text",
              "analyzer": "my_analyzer",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            },
            "age" : { 
              "type" : "text"             <--- I am not sure why this is text. Change it to long or int. Would leave this to you
            },
            "status" : { 
              "type" : "text",
              "analyzer": "my_analyzer",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            },
            "tests":{ 
              "type" : "nested" 
            }
        }
    }
}

請注意,在上面的映射中,我以nameemailstatus的關鍵字形式創建了一個兄弟字段,如下所示:

"name":{ 
   "type":"text",
   "analyzer":"my_analyzer",
   "fields":{ 
      "keyword":{ 
         "type":"keyword"
      }
   }
}

現在您的查詢可以像下面這樣簡單。

詢問:

POST student_detail/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "war"                      <---- Note this. This would even return documents having "Schwarb"
          }
        },
        {
          "match": {
            "email": "gmail"                   <---- Note this
          }
        },
        {
          "nested": {
            "path": "tests",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "tests.test_id": 587
                    }
                  },
                  {
                    "range": {
                      "tests.test_score": {
                        "gte": 5
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

請注意,對於完全匹配,我將在關鍵字字段上使用術語查詢,而對於SQL中的正常搜索或LIKE ,我將在文本字段上使用簡單的匹配查詢前提是它們使用Ngram Tokenizer

另請注意,對於>=<=您將需要使用Range Query

回復:

{
  "took" : 233,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.7260926,
    "hits" : [
      {
        "_index" : "student_detail",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.7260926,
        "_source" : {
          "id" : 123,
          "name" : "Schwarb",
          "email" : "abc@gmail.com",
          "status" : "current",
          "age" : 14,
          "tests" : [
            {
              "test_id" : 587,
              "test_score" : 10
            },
            {
              "test_id" : 588,
              "test_score" : 6
            }
          ]
        }
      }
    ]
  }
}

請注意,我在運行查詢時的回復中觀察到您在問題中提到的文檔。

請閱讀我分享的鏈接。 了解這些概念至關重要。 希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM