ใช้การค้นหา SQL Connect

Firebase SQL Connect ช่วยให้คุณสร้างเครื่องมือเชื่อมต่อสำหรับอินสแตนซ์ PostgreSQL ที่จัดการด้วย Cloud SQL ได้ เครื่องมือเชื่อมต่อเหล่านี้เป็นการรวมกันของคำค้นหาและการเปลี่ยนแปลงเพื่อใช้ข้อมูลจากสคีมาของคุณ

คู่มือเริ่มต้นใช้งานได้แนะนำสคีมาแอปรีวิวภาพยนตร์สำหรับ PostgreSQL

คู่มือดังกล่าวยังแนะนำการดำเนินการด้านการดูแลระบบทั้งแบบที่นำไปใช้ได้จริงและแบบเฉพาะกิจ ซึ่งรวมถึงการค้นหาด้วย

  • การค้นหาที่ทำให้ใช้งานได้คือการค้นหาที่คุณใช้เพื่อเรียกจากแอปไคลเอ็นต์ โดยมีปลายทาง API ที่คุณกำหนด คุณรวมไฟล์เหล่านี้ไว้ในเครื่องมือเชื่อมต่อที่ติดตั้งใช้งานในเซิร์ฟเวอร์ เครื่องมือ SQL Connect จะสร้าง SDK ของไคลเอ็นต์ตาม API ของคุณ การค้นหาที่ติดตั้งใช้งานจะไม่ได้รับการปกป้องโดยนโยบาย IAM ดังนั้นโปรดรักษาความปลอดภัยโดยใช้คำสั่ง SQL Connect @auth
  • การค้นหาของผู้ดูแลระบบเฉพาะกิจจะทำงานจากสภาพแวดล้อมที่มีสิทธิ์เพื่ออ่านข้อมูล คุณสามารถสร้างและเรียกใช้ได้ในคอนโซล Firebase หรือในสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ในเครื่องโดยใช้ส่วนขยาย SQL Connect VS Code

คู่มือนี้จะเจาะลึกเกี่ยวกับคำค้นหาที่ทำให้ใช้งานได้

ฟีเจอร์ของคำค้นหา SQL Connect รายการ

SQL Connect ช่วยให้คุณทำการค้นหาพื้นฐานได้ในทุกรูปแบบที่คุณคาดหวังจากฐานข้อมูล PostgreSQL

แต่ด้วยส่วนขยายของ SQL Connect สำหรับ GraphQL คุณสามารถใช้การค้นหาขั้นสูงเพื่อแอปที่เร็วและมีประสิทธิภาพมากขึ้นได้

  • ใช้สเกลาร์คีย์ที่แสดงผลจากการดำเนินการหลายอย่างเพื่อลดความซับซ้อนของการดำเนินการซ้ำๆ ในระเบียน
  • ทำการค้นหาในระหว่างการดำเนินการกลายพันธุ์แบบหลายขั้นตอนเพื่อค้นหาข้อมูล ซึ่งช่วยประหยัดบรรทัดโค้ดและรอบการเดินทางไป-กลับไปยังเซิร์ฟเวอร์

ใช้ฟิลด์ที่สร้างขึ้นเพื่อสร้างการค้นหา

การดำเนินการ SQL Connect จะขยายชุดฟิลด์ที่ SQL Connect สร้างขึ้นโดยอัตโนมัติตามประเภทและความสัมพันธ์ของประเภทในสคีมา เครื่องมือในเครื่องจะสร้างช่องเหล่านี้เมื่อใดก็ตามที่คุณแก้ไขสคีมา

คุณสามารถใช้ฟิลด์ที่สร้างขึ้นเพื่อใช้การค้นหาที่ซับซ้อนมากขึ้น ตั้งแต่การดึงข้อมูลระเบียนเดี่ยวหรือหลายระเบียนจากตารางเดียวไปจนถึงหลายระเบียนจากตารางที่เกี่ยวข้อง

สมมติว่าสคีมามีประเภท Movie และประเภท Actor ที่เชื่อมโยง SQL Connect จะสร้าง movie, movies, actors_on_movies ฟิลด์ และอื่นๆ

คำค้นหาที่มีช่อง
movie

ช่อง movie แสดงถึงระเบียนเดียวในตาราง Movie

ใช้ช่องนี้เพื่อค้นหาภาพยนตร์เรื่องเดียวตามคีย์

query GetMovie($myKey: Movie_Key!) {
  movie(key: $myKey) { title }
}

คำค้นหาที่มีช่อง
movies

ฟิลด์ movies แสดงรายการระเบียนในตาราง Movie

ใช้ช่องนี้เพื่อค้นหาภาพยนตร์หลายเรื่อง เช่น ภาพยนตร์ทั้งหมดที่มีปีที่ระบุ

query GetMovies($myYear: Int!) {
  movies(where: { year: { eq: $myYear } }) { title }
}

คำค้นหาที่มีช่อง
actors_on_movies

ช่อง actors_on_movies แสดงรายการบันทึกที่เชื่อมต่อตาราง Actor และ Movie ใช้ช่องนี้เพื่อค้นหานักแสดงทั้งหมดที่เกี่ยวข้องกับภาพยนตร์ที่ระบุ

ใช้ช่องนี้เพื่อค้นหานักแสดงทั้งหมดที่เกี่ยวข้องกับภาพยนตร์ที่ระบุ

  query GetActorsOnMovie($myKey: Movie_Key!) {
    actors_on_movies(where: { movie: { key: { eq: $myKey } } }) {
      actor { name }
    }
  }

องค์ประกอบสำคัญของคำค้นหา

การค้นหา SQL Connect เป็นการค้นหา GraphQL ที่มีส่วนขยาย SQL Connect คุณสามารถกำหนดชื่อการดำเนินการและรายการตัวแปร GraphQL ได้เช่นเดียวกับการค้นหา GraphQL ทั่วไป

SQL Connect ขยายการค้นหา GraphQL ด้วยคำสั่งที่กำหนดเอง เช่น @auth

ดังนั้นการค้นหาต่อไปนี้จึงมีข้อมูลต่อไปนี้

  • คำจำกัดความของประเภท query
  • ชื่อการดำเนินการ (การค้นหา) ListMoviesByGenre
  • อาร์กิวเมนต์การค้นหาเดียว ซึ่งในที่นี้คือตัวแปร $genre ของประเภท String
  • คำสั่งเดียว @auth
  • ช่องเดียว movies
query ListMoviesByGenre($genre: String!) @auth(level: PUBLIC) {
  movies(where: { genre: { eq: $genre } }) {
    id
    title
  }
}

อาร์กิวเมนต์การค้นหาทุกรายการต้องมีการประกาศประเภท ซึ่งเป็นประเภทในตัว เช่น String หรือประเภทที่กำหนดเองซึ่งกำหนดสคีมา เช่น Movie

คู่มือนี้จะพิจารณาลักษณะของคำค้นหาที่ซับซ้อนมากขึ้นเรื่อยๆ คุณจะปิดท้ายด้วยการแนะนำนิพจน์ความสัมพันธ์ที่กระชับและมีประสิทธิภาพซึ่งคุณสามารถใช้เพื่อสร้างการค้นหาที่นำไปใช้ได้

สเกลาร์หลักในคำค้นหา

แต่ก่อนอื่น เรามาพูดถึงสเกลาร์คีย์กันก่อน

SQL Connect กำหนดสเกลาร์คีย์พิเศษเพื่อแสดงคีย์หลักของแต่ละตาราง ซึ่งระบุโดย {TableType}_Key ซึ่งเป็นออบเจ็กต์ JSON ของค่าคีย์หลัก

คุณจะดึงข้อมูลสเกลาร์คีย์เป็นการตอบกลับที่แสดงโดยฟิลด์การอ่านที่สร้างขึ้นโดยอัตโนมัติส่วนใหญ่ หรือแน่นอนว่าจากการค้นหาที่คุณดึงข้อมูลฟิลด์ทั้งหมดที่จำเป็นในการสร้างคีย์สเกลาร์

การค้นหาอัตโนมัติแบบเอกพจน์ เช่น movie ในตัวอย่างที่กำลังทำงานอยู่ รองรับอาร์กิวเมนต์คีย์ที่ยอมรับสเกลาร์คีย์

คุณอาจส่งสเกลาร์คีย์เป็นลิเทอรัล แต่คุณสามารถกำหนดตัวแปรเพื่อส่งสเกลาร์คีย์เป็นอินพุตได้

การค้นหา

query GetMovie($myKey: Movie_Key!) {
  movie(key: $myKey) { title }
}
    

การตอบสนอง

{
  "data": {
    "movie": {
      "title": "Example Movie Title"
    }
  }
}
    

ซึ่งสามารถระบุใน JSON คำขอได้ดังนี้ (หรือรูปแบบการเรียงลำดับอื่นๆ)

{
  # …
  "variables": {
    "myKey": {"id": "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"}
  }
}

การแยกวิเคราะห์สเกลาร์ที่กำหนดเองช่วยให้สร้าง Movie_Key โดยใช้ไวยากรณ์ออบเจ็กต์ซึ่งอาจมีตัวแปรได้ด้วย ซึ่งจะมีประโยชน์มากที่สุดเมื่อคุณต้องการแยกคอมโพเนนต์แต่ละรายการออกเป็นตัวแปรต่างๆ ด้วยเหตุผลบางประการ

เขียนการค้นหาพื้นฐาน

คุณสามารถเริ่มเขียนคำค้นหาเพื่อรับระเบียนแต่ละรายการจากฐานข้อมูล หรือแสดงรายการระเบียนจากตารางที่มีตัวเลือกในการจำกัดและจัดลำดับผลลัพธ์

ดึงข้อมูลบันทึกแต่ละรายการ

การค้นหาที่ง่ายที่สุดจะดึงข้อมูลระเบียนเดียวตามรหัส การค้นหาจะใช้ช่อง movie ที่สร้างขึ้นโดยอัตโนมัติ

การค้นหา

query GetMovieById($id: UUID!) @auth(level: PUBLIC) {
  movie(id: $id) {
    id
    title
    imageUrl
    genre
  }
}
    

การตอบสนอง

{
  "data": {
    "movie": {
      "id": "some-uuid",
      "title": "Example Movie Title",
      "imageUrl": "https://example.com/movie.jpg",
      "genre": "Action"
    }
  }
}
    

ดึงข้อมูลระเบียนทั้งหมดในตาราง

หากต้องการดึงข้อมูลชุดย่อยของฟิลด์สำหรับรายการภาพยนตร์ทั้งหมดจากตาราง Movies การค้นหาของคุณจะใช้ฟิลด์ movies ที่สร้างขึ้นโดยอัตโนมัติ และการติดตั้งใช้งานของคุณอาจมีลักษณะดังต่อไปนี้

การค้นหา

query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    genre
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title",
        "imageUrl": "https://example.com/movie.jpg",
        "genre": "Action"
      },
      {
        "id": "another-uuid",
        "title": "Another Movie Title",
        "imageUrl": "https://example.com/another-movie.jpg",
        "genre": "Comedy"
      }
    ]
  }
}
    

ใช้โอเปอเรเตอร์ orderBy, limit และ offset

แน่นอนว่าการแสดงรายการระเบียนทั้งหมดจากตารางมีประโยชน์ที่จำกัด

คุณสามารถจัดเรียงและแบ่งหน้าผลลัพธ์ได้ ระบบยอมรับอาร์กิวเมนต์เหล่านี้ แต่จะไม่แสดงในผลลัพธ์

ในกรณีนี้ คำค้นหาจะดึงชื่อภาพยนตร์ 10 อันดับแรกตามคะแนน

การค้นหา

query MoviesTop10 {
  movies(orderBy: [{ rating: DESC }], limit: 10) {
    # graphql: list the fields from the results to return
    title
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      { "title": "Top Movie 1" },
      { "title": "Top Movie 2" },
      { "title": "Top Movie 3" }
      // ... other 7 movies
    ]
  }
}
    

คุณอาจมี Use Case สำหรับการดึงข้อมูลแถวจากออฟเซ็ต เช่น ภาพยนตร์ 11-20 เรื่องที่จัดเรียงตามคะแนน

การค้นหา

query Movies11to20 {
  movies(orderBy: [{ rating: DESC }], limit: 10, offset: 10) {
    # graphql: list the fields from the results to return
    title
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      { "title": "Movie 11" },
      { "title": "Movie 12" },
      { "title": "Movie 13" }
      // ... other 7 movies
    ]
  }
}
    

ใช้นามแฝงในการค้นหา

SQL Connect รองรับการตั้งชื่อแทน GraphQL ในการค้นหา ชื่อแทนช่วยให้คุณเปลี่ยนชื่อข้อมูลที่แสดงในผลการค้นหาได้ การค้นหา SQL Connect รายการเดียวสามารถใช้ตัวกรองหลายรายการหรือการดำเนินการค้นหาอื่นๆ ในคำขอที่มีประสิทธิภาพรายการเดียวไปยังเซิร์ฟเวอร์ ซึ่งจะออก "การค้นหาย่อย" หลายรายการพร้อมกันได้อย่างมีประสิทธิภาพ เพื่อหลีกเลี่ยงการชนกันของชื่อในชุดข้อมูลที่แสดงผล คุณจึงใช้ชื่อแทนเพื่อแยกความแตกต่างของการค้นหาย่อย

ต่อไปนี้คือการค้นหาที่นิพจน์ใช้นามแฝง mostPopular และ leastPopular

การค้นหา

query ReviewPopularitySpread($genre: String) {
  mostPopular: review(
    first: {
      where: {genre: {eq: $genre}},
      orderBy: {popularity: DESC}
    }
  ),
  leastPopular: review(
    last: {
      where: {genre: {eq: $genre}},
      orderBy: {popularity: DESC}
    }
  )
}
    

การตอบสนอง

{
  "data": {
    "mostPopular": [
      { "popularity": 9 }
    ],
    "leastPopular": [
      { "popularity": 1 }
    ]
  }
}
    

ใช้ตัวกรองการค้นหา

การค้นหา SQL Connect จะจับคู่กับตัวกรอง SQL ทั่วไปและการดำเนินการตามลำดับทั้งหมด

กรองด้วยโอเปอเรเตอร์ where ที่มี orderBy

แสดงแถวที่ตรงกันทั้งหมดจากตาราง (และการเชื่อมโยงที่ฝังอยู่) แสดงอาร์เรย์ว่างหากไม่มีระเบียนที่ตรงกับตัวกรอง

การค้นหา

query MovieByTopRating($genre: String) {
  mostPopular: movies(
    where: { genre: { eq: $genre } },
    orderBy: { rating: DESC }
  ) {
    # graphql: list the fields from the results to return
    id
    title
    genre
    description
  }
}
    

การตอบสนอง

{
  "data": {
    "mostPopular": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title",
        "genre": "Action",
        "description": "A great movie"
      }
    ]
  }
}
    

กรองโดยการทดสอบค่า Null

คุณทดสอบค่า null ได้โดยใช้โอเปอเรเตอร์ isNull

การค้นหา

query ListMoviesWithoutDescription {
  movies(where: { description: { isNull: true }}) {
    id
    title
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title"
      },
      {
        "id": "another-uuid",
        "title": "Another Movie Title"
      }
    ]
  }
}
    

ดูโอเปอเรเตอร์เพิ่มเติมได้ที่คู่มืออ้างอิงประเภทออบเจ็กต์อินพุต

กรองด้วยการเปรียบเทียบค่า

คุณสามารถใช้โอเปอเรเตอร์ เช่น lt (น้อยกว่า) และ ge (มากกว่าหรือเท่ากับ) เพื่อเปรียบเทียบค่าในคำค้นหาได้

การค้นหา

query ListMoviesByRating($minRating: Int!, $maxRating: Int!) {
  movies(where: { rating: { ge: $minRating, lt: $maxRating }}) {
    id
    title
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title"
      },
      {
        "id": "another-uuid",
        "title": "Another Movie Title"
      }
    ]
  }
}
    

กรองด้วยโอเปอเรเตอร์ includes และ excludes สำหรับช่องอาร์เรย์

คุณสามารถทดสอบได้ว่าช่องอาร์เรย์มีรายการที่ระบุหรือไม่

ตัวอย่างต่อไปนี้แสดงโอเปอเรเตอร์ includes

SQL Connect รองรับ includesAll, excludes, excludesAll และอื่นๆ ตรวจสอบโอเปอเรเตอร์ทั้งหมดดังกล่าวสำหรับจำนวนเต็ม สตริง วันที่ และประเภทข้อมูลอื่นๆ ในส่วนหัว _ListFilter ของเอกสารอ้างอิง

การค้นหา

query ListMoviesByTag($tag: String!) {
  movies(where: { tags: { includes: $tag }}) {
    # graphql: list the fields from the results to return
    id
    title
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title"
      }
    ]
  }
}
    

กรองด้วยการดำเนินการกับสตริงและนิพจน์ทั่วไป

การค้นหาของคุณสามารถใช้การค้นหาสตริงและการเปรียบเทียบทั่วไปได้ ซึ่งรวมถึงนิพจน์ทั่วไป โปรดทราบว่าเพื่อประสิทธิภาพ คุณกำลังรวมการดำเนินการหลายอย่างไว้ที่นี่และแยกความกำกวมด้วยชื่อแทน

query MoviesTitleSearch($prefix: String, $suffix: String, $contained: String, $regex: String) {
  prefixed: movies(where: {title: {startsWith: $prefix}}) {...}
  suffixed: movies(where: {title: {endsWith: $suffix}}) {...}
  contained: movies(where: {title: {contains: $contained}}) {...}
}

กรองด้วยตรรกะโอเปอเรเตอร์ _or, _and, _not

ใช้ _or สำหรับตรรกะที่ซับซ้อนมากขึ้น SQL Connect ยังรองรับโอเปอเรเตอร์ _and และ _not ด้วย

การค้นหา

query ListMoviesByGenreAndGenre($minRating: Int!, $genre: String) {
  movies(
    where: { _or: [{ rating: { ge: $minRating } }, { genre: { eq: $genre } }] }
  ) {
    # graphql: list the fields from the results to return
    title
  }
}
    

การตอบสนอง

{
  "data": {
    "movies": [
      { "title": "Movie Title 1" },
      { "title": "Movie Title 2" }
    ]
  }
}
    

เขียนคำค้นหาเชิงสัมพันธ์

การค้นหา SQL Connect สามารถเข้าถึงข้อมูลตามความสัมพันธ์ระหว่างตารางได้ คุณสามารถใช้ความสัมพันธ์แบบออบเจ็กต์ (1 ต่อ 1) หรืออาร์เรย์ (1 ต่อหลาย) ที่กำหนดไว้ในสคีมาเพื่อสร้างการค้นหาที่ซ้อนกัน กล่าวคือ ดึงข้อมูลสำหรับประเภทหนึ่งพร้อมกับข้อมูลจากประเภทที่ซ้อนกันหรือเกี่ยวข้อง

การค้นหาดังกล่าวใช้ไวยากรณ์ SQL Connect _on_ และ _via ในช่องอ่านที่สร้างขึ้น

อย่าลืมตรวจสอบสคีมาตัวอย่าง

หลายรายการต่อหนึ่งรายการ

ตอนนี้มาดูการค้นหาเพื่อแสดงไวยากรณ์ _on_ กัน

การค้นหา

query MyReviews @auth(level: USER) {
  user(key: {id_expr: "auth.uid"}) {
    reviews: reviews_on_user {
      movie { name }
      rating
    }
  }
}
    

การตอบสนอง

{
  "data": {
    "user": {
      "reviews": [
        {
          "movie": { "name": "Movie Title" },
          "rating": 5
        }
      ]
    }
  }
}
    

แบบตัวต่อตัว

คุณสามารถเขียนการค้นหาแบบหนึ่งต่อหนึ่งโดยใช้ไวยากรณ์ _on_

การค้นหา

query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
  movie(id: $id) {
    movieMetadatas_on_movie {
      director
    }
  }
}
    

การตอบสนอง

{
  "data": {
    "movie": {
      "movieMetadatas_on_movie": {
        "director": "Some Director"
      }
    }
  }
}
    

แบบกลุ่มต่อกลุ่ม

การค้นหาแบบหลายต่อหลายใช้ไวยากรณ์ _via_ การค้นหาแบบหลายต่อหลายอาจดึงข้อมูลนักแสดงสำหรับภาพยนตร์ที่ระบุ

การค้นหา

query MoviesActors($id: UUID!) @auth(level: USER) {
  movie(id: $id) {
     actors: actors_via_MovieActors {
        name
     }
  }
}
    

การตอบสนอง

{
  "data": {
    "movie": {
      "actors": [
        {
          "name": "Actor Name"
        }
      ]
    }
  }
}
    

แต่เราสามารถเขียนคำค้นหาที่ซับซ้อนมากขึ้นโดยใช้นามแฝงเพื่อกรองตาม role เพื่อดึงข้อมูลนักแสดงและภาพยนตร์ที่เกี่ยวข้องในผลลัพธ์ mainActors และ supportingActors เนื่องจากเป็นความสัมพันธ์แบบหลายต่อหลาย จึงต้องใช้ไวยากรณ์ _via_

การค้นหา

query GetMovieCast($movieId: UUID!, $actorId: UUID!) @auth(level: PUBLIC) {
  movie(id: $movieId) {
    mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) {
      name
    }
    supportingActors: actors_via_MovieActor(
      where: { role: { eq: "supporting" } }
    ) {
      name
    }
  }
  actor(id: $actorId) {
    mainRoles: movies_via_MovieActor(where: { role: { eq: "main" } }) {
      title
    }
    supportingRoles: movies_via_MovieActor(
      where: { role: { eq: "supporting" } }
    ) {
      title
    }
  }
}
    

การตอบสนอง

{
  "data": {
    "movie": {
      "mainActors": [
        {
          "name": "Main Actor Name"
        }
      ],
      "supportingActors": [
        {
          "name": "Supporting Actor Name"
        }
      ]
    },
    "actor": {
      "mainRoles": [
        {
          "title": "Main Role Movie Title"
        }
      ],
      "supportingRoles": [
        {
          "title": "Supporting Role Movie Title"
        }
      ]
    }
  }
}
    

การค้นหาการรวมข้อมูล

การรวมคืออะไร และเหตุใดจึงควรใช้

ฟิลด์รวมช่วยให้คุณทำการคำนวณในรายการผลลัพธ์ได้ เมื่อใช้ช่องรวม คุณจะทำสิ่งต่างๆ ต่อไปนี้ได้

  • ดูคะแนนเฉลี่ยของรีวิว
  • ดูค่าใช้จ่ายรวมของสินค้าในรถเข็นช็อปปิ้ง
  • ค้นหาผลิตภัณฑ์ที่ได้รับคะแนนสูงสุดหรือต่ำสุด
  • นับจำนวนผลิตภัณฑ์ในร้านค้า

การรวมข้อมูลจะดำเนินการบนเซิร์ฟเวอร์ ซึ่งมีข้อดีหลายประการเมื่อเทียบกับการคำนวณในฝั่งไคลเอ็นต์ ดังนี้

  • ประสิทธิภาพของแอปที่เร็วขึ้น (เนื่องจากคุณหลีกเลี่ยงการคํานวณฝั่งไคลเอ็นต์)
  • ลดค่าใช้จ่ายในการส่งออกข้อมูล (เนื่องจากคุณส่งเฉพาะผลลัพธ์ที่รวบรวมไว้แทนอินพุตทั้งหมด)
  • ความปลอดภัยที่ได้รับการปรับปรุง (เนื่องจากคุณสามารถให้สิทธิ์เข้าถึงข้อมูลรวมแก่ลูกค้าแทนที่จะเป็นชุดข้อมูลทั้งหมด)

ตัวอย่างสคีมาสำหรับการรวม

ในส่วนนี้ เราจะเปลี่ยนไปใช้สคีมาตัวอย่างหน้าร้าน ซึ่งเหมาะสำหรับการอธิบายวิธีใช้การรวมข้อมูล

  type Product @table {
    name: String!
    manufacturer: String!
    quantityInStock: Int!
    price: Float!
    expirationDate: Date
  }

การรวมข้อมูลแบบง่าย

_count สำหรับทุกช่อง

ช่องรวมที่ง่ายที่สุดคือ _count ซึ่งจะแสดงจำนวนแถวที่ตรงกับคำค้นหาของคุณ สำหรับแต่ละฟิลด์ในประเภทของคุณ SQL Connect จะสร้างฟิลด์รวมที่สอดคล้องกันโดยขึ้นอยู่กับประเภทฟิลด์

การค้นหา

query CountProducts {
  products {
    _count
  }
}

การตอบสนอง
one

ตัวอย่างเช่น หากคุณมีผลิตภัณฑ์ 5 รายการในฐานข้อมูล ผลลัพธ์จะเป็นดังนี้

{
  "products": [
    {
    "_count": 5
    }
  ]
}

ทุกฟิลด์จะมีฟิลด์ <field>_count ซึ่งจะนับจำนวนแถวที่มีค่าที่ไม่ใช่ค่า Null ในฟิลด์นั้น

การค้นหา

query CountProductsWithExpirationDate {
  products {
    expirationDate_count
  }
}

การตอบสนอง
field_count

ตัวอย่างเช่น หากคุณมีผลิตภัณฑ์ 3 รายการที่มีวันที่หมดอายุ ผลลัพธ์จะเป็นดังนี้

{
  "products": [
    {
    "expirationDate_count": 3
    }
  ]
}
_min, _max, _sum และ _avg สำหรับช่องตัวเลข

ช่องตัวเลข (int, float, int64) ยังมี <field>_min, <field>_max, <field>_sum และ <field>_avg ด้วย

การค้นหา

query NumericAggregates {
  products {
  quantityInStock_max
  price_min
  price_avg
  quantityInStock_sum
  }
}

การตอบสนอง
_min _max _sum _avg

ตัวอย่างเช่น หากคุณมีผลิตภัณฑ์ต่อไปนี้

  • ผลิตภัณฑ์ ก: quantityInStock: 10, price: 2.99
  • ผลิตภัณฑ์ ข: quantityInStock: 5, price: 5.99
  • ผลิตภัณฑ์ C: quantityInStock: 20, price: 1.99

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "products": [
    {
    "quantityInStock_max": 20,
    "price_min": 1.99,
    "price_avg": 3.6566666666666666,
    "quantityInStock_sum": 35
    }
  ]
}
_min และ _max สำหรับวันที่และการประทับเวลา

ช่องวันที่และการประทับเวลามี <field>_min และ <field>_max

การค้นหา

query DateAndTimeAggregates {
  products {
  expirationDate_max
  expirationDate_min
  }
}

การตอบสนอง
_min _maxdatetime

ตัวอย่างเช่น หากคุณมีวันที่หมดอายุต่อไปนี้

  • ผลิตภัณฑ์ ก: 2024-01-01
  • ผลิตภัณฑ์ ข: 2024-03-01
  • ผลิตภัณฑ์ ค: 2024-02-01

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "products": [
    {
    "expirationDate_max": "2024-03-01",
    "expirationDate_min": "2024-01-01"
    }
  ]
}

แตกต่าง

อาร์กิวเมนต์ distinct ช่วยให้คุณได้รับค่าที่ไม่ซ้ำกันทั้งหมดสำหรับฟิลด์ (หรือชุดค่าผสมของฟิลด์) เช่น

การค้นหา

query ListDistinctManufacturers {
  products(distinct: true) {
    manufacturer
  }
}

การตอบสนอง
distinct

ตัวอย่างเช่น หากคุณมีผู้ผลิตต่อไปนี้

  • ผลิตภัณฑ์ ก: manufacturer: "Acme"
  • ผลิตภัณฑ์ ข: manufacturer: "Beta"
  • ผลิตภัณฑ์ ค: manufacturer: "Acme"

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "products": [
    { "manufacturer": "Acme" },
    { "manufacturer": "Beta" }
  ]
}

คุณยังใช้อาร์กิวเมนต์ distinct ในช่องรวมเพื่อรวมค่าที่แตกต่างกันแทนได้ด้วย เช่น

การค้นหา

query CountDistinctManufacturers {
  products {
    manufacturer_count(distinct: true)
  }
}

การตอบสนอง
distinctonaggregate

ตัวอย่างเช่น หากคุณมีผู้ผลิตต่อไปนี้

  • ผลิตภัณฑ์ ก: manufacturer: "Acme"
  • ผลิตภัณฑ์ ข: manufacturer: "Beta"
  • ผลิตภัณฑ์ ค: manufacturer: "Acme"

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "products": [
    {
    "manufacturer_count": 2
    }
  ]
}

การรวมข้อมูลแบบจัดกลุ่ม

คุณดำเนินการรวมแบบจัดกลุ่มโดยเลือกช่องรวมและช่องที่ไม่รวมในประเภทหนึ่งๆ ซึ่งจะจัดกลุ่มแถวที่ตรงกันทั้งหมดซึ่งมีค่าเดียวกันสำหรับช่องที่ไม่ใช่การรวม และคำนวณช่องการรวมสำหรับกลุ่มนั้น เช่น

การค้นหา

query MostExpensiveProductByManufacturer {
  products {
  manufacturer
  price_max
  }
}

การตอบสนอง
groupedaggregates

ตัวอย่างเช่น หากคุณมีผลิตภัณฑ์ต่อไปนี้

  • ผลิตภัณฑ์ ก: manufacturer: "Acme", price: 2.99
  • ผลิตภัณฑ์ ข: manufacturer: "Beta", price: 5.99
  • ผลิตภัณฑ์ C: manufacturer: "Acme", price: 1.99

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "products": [
    { "manufacturer": "Acme", "price_max": 2.99 },
    { "manufacturer": "Beta", "price_max": 5.99 }
  ]
}
having และ where ที่มีข้อมูลรวมแบบจัดกลุ่ม

นอกจากนี้ คุณยังใช้อาร์กิวเมนต์ having และ where เพื่อแสดงเฉพาะกลุ่มที่ตรงตามเกณฑ์ที่ระบุได้ด้วย

  • having ช่วยให้คุณกรองกลุ่มตามช่องรวมได้
  • where ช่วยให้คุณกรองแถวตามช่องที่ไม่ใช่การรวมได้

การค้นหา

query FilteredMostExpensiveProductByManufacturer {
  products(having: {price_max: {ge: 2.99}}) {
  manufacturer
  price_max
  }
}

การตอบสนอง
havingwhere

ตัวอย่างเช่น หากคุณมีผลิตภัณฑ์ต่อไปนี้

  • ผลิตภัณฑ์ ก: manufacturer: "Acme", price: 2.99
  • ผลิตภัณฑ์ ข: manufacturer: "Beta", price: 5.99
  • ผลิตภัณฑ์ C: manufacturer: "Acme", price: 1.99

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "products": [
    { "manufacturer": "Acme", "price_max": 2.99 },
    { "manufacturer": "Beta", "price_max": 5.99 }
  ]
}

รวมข้อมูลในตารางต่างๆ

คุณสามารถใช้ช่องรวมร่วมกับช่องความสัมพันธ์แบบ 1 ต่อหลายที่สร้างขึ้นเพื่อตอบคำถามที่ซับซ้อนเกี่ยวกับข้อมูลของคุณได้ ต่อไปนี้คือสคีมาที่แก้ไขแล้วซึ่งมีตาราง Manufacturer แยกต่างหากที่เราใช้ในตัวอย่างได้

  type Product @table {
    name: String!
    manufacturer: Manufacturer!
    quantityInStock: Int!
    price: Float!
    expirationDate: Date
  }

  type Manufacturer @table {
    name: String!
    headquartersCountry: String!
  }

ตอนนี้เราสามารถใช้ช่องรวมเพื่อทำสิ่งต่างๆ เช่น ค้นหาจำนวนผลิตภัณฑ์ที่ผู้ผลิตผลิตได้

การค้นหา

query GetProductCount($id: UUID) {
  manufacturers {
    name
    products_on_manufacturer {
      _count
    }
  }
}

การตอบสนอง
aggregatesacrosstables

ตัวอย่างเช่น หากคุณมีผู้ผลิตต่อไปนี้

  • ผู้ผลิต ก: name: "Acme", products_on_manufacturer: 2
  • ผู้ผลิต B: name: "Beta", products_on_manufacturer: 1

ผลลัพธ์ที่ได้จะเป็นดังนี้

{
  "manufacturers": [
    { "name": "Acme", "products_on_manufacturer": { "_count": 2 } },
    { "name": "Beta", "products_on_manufacturer": { "_count": 1 } }
  ]
}

ช่องการแจงนับการค้นหา

คุณสามารถค้นหาฟิลด์การแจงนับในสคีมาได้

สมมติว่าการแจงนับของเรามีการใช้งานดังนี้

enum AspectRatio {
   ACADEMY
   WIDESCREEN
   ANAMORPHIC
   IMAX
   "No information available on aspect ratio"
   UNAVAILABLE
}

เช่น คุณสามารถแสดงภาพยนตร์ทั้งหมดที่จัดรูปแบบในสัดส่วนภาพที่ต้องการได้

query ListMoviesByAspectRatio($aspectRatio: AspectRatio!) @auth(level: PUBLIC) {
  movies(where:
    {originalAspectRatio: {eq: $aspectRatio}}
) {
    id
    title
    imageUrl
    releaseYear
    genre
    rating
    tags
    description
    otherAspectRatios
  }
}

กรองช่องการแจงนับ

Enum มีการดำเนินการกรองมาตรฐานที่ใช้ได้ ได้แก่ eq, ne, ge, gt, lt, le, in nin รวมถึง includes, excludes, includesAll และ excludesAll สำหรับรายการ

ใน order โอเปอเรเตอร์มากกว่าและน้อยกว่าจะใช้ลำดับของค่า enum เพื่อให้การดำเนินการมีความหมาย ค่าที่จุดเริ่มต้นของ enum จะน้อยกว่าค่าที่จุดสิ้นสุดของคำจำกัดความ enum

ตัวอย่างเช่น ส่วนคำสั่ง where ต่อไปนี้จะแสดงภาพยนตร์ทั้งหมดที่มีratioน้อยกว่าสัดส่วนภาพที่ป้อน

  • ในตัวอย่างแรก หาก $aspectRatio เป็น IMAX ระบบจะเลือกภาพยนตร์ที่มี ratio ตรงกับ ACADEMY, WIDESCREEN และ ANAMORPHIC
  • ในตัวอย่างที่ 2 ระบบจะแสดงเฉพาะภาพยนตร์ที่มีทั้งใน ACADEMY และ WIDESCREEN
  movies(where: {originalAspectRatio: {lt: $aspectRatio}})

  movies(where: {otherAspectRatios: {includesAll: [ACADEMY, WIDESCREEN]}})

ดำเนินการค้นหาการรวมในช่องการแจงนับ

รองรับเฉพาะ _count สำหรับ Enum

การค้นหาต่อไปนี้จะนับจำนวนภาพยนตร์ทั้งหมดของสัดส่วนภาพแต่ละแบบ

query MovieCountByOriginalAspectRatio @auth(level: PUBLIC) {
  movies {
    _count
    originalAspectRatio
  }
}

เรียกใช้การค้นหาการแจงนับจากโค้ดไคลเอ็นต์

ดูวิธีใช้การค้นหาการแจงนับจากไคลเอ็นต์ และวิธีออกแบบการเรียกใช้ไคลเอ็นต์เพื่อเพิ่มความยืดหยุ่นในการจัดการการแจงนับได้สูงสุดในคู่มือ SDK สำหรับ iOS, Android, เว็บ และ Flutter

เขียนการค้นหาขั้นสูง: ใช้ช่อง query เพื่ออ่านข้อมูลในการดำเนินการแบบหลายขั้นตอน

มีหลายสถานการณ์ที่คุณอาจต้องการอ่านฐานข้อมูลระหว่างการดำเนินการเปลี่ยนแปลงเพื่อค้นหาและยืนยันข้อมูลที่มีอยู่ก่อนดำเนินการ เช่น การแทรกหรือการอัปเดต ตัวเลือกเหล่านี้จะช่วยประหยัดการดำเนินการไปกลับและลดค่าใช้จ่าย

SQL Connect รองรับฟังก์ชันการทำงานนี้ ดูการดำเนินการแบบหลายขั้นตอน

ขั้นตอนถัดไป

คุณอาจสนใจสิ่งต่อไปนี้