Π€ΡΠ½ΠΊΡΠΈΡ | API Searchkit | API ReactiveSearch |
---|---|---|
ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π·Π°ΠΏΡΠΎΡΠ° | GraphQL API | REST API (ΠΏΠΎΡ ΠΎΠΆΠΈΠ΅ Π½Π° Elasticsearch DSL) |
ΠΠ°ΡΡΠΎΠΌΠΈΠ·Π°ΡΠΈΡ | ΠΠΎΠ³ΠΈΠΊΠ° Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅ | ΠΠΎΠ³ΠΈΠΊΠ° Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΡΡΡ ΡΠ΅ΡΠ΅Π· REST API ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ Π½Π° ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π΅ |
ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ | Π Π°Π±ΠΎΡΠ°Π΅Ρ ΠΊΠ°ΠΊ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΠΉ ΡΠ»ΠΎΠΉ (GraphQL-ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ Π·Π°ΡΠΈΡΠ°Π΅Ρ Elasticsearch). ΠΠΌΠ΅ΡΡΠΎ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π·Π°ΠΏΡΠΎΡΠ° Π½Π°ΠΏΡΡΠΌΡΡ Π² Elasticsearch API, Π²Ρ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΠ΅ GraphQL Π·Π°ΠΏΡΠΎΡ (Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ ΠΏΠΎΠΈΡΠΊΠ° Π² Π²ΠΈΠ΄Π΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ) Π² Searchkit API. Searchkit Π·Π°ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡ ΡΡΠΎΡ GraphQL Π·Π°ΠΏΡΠΎΡ Π² Elasticsearch DSL | Π Π°Π±ΠΎΡΠ°Π΅Ρ ΠΊΠ°ΠΊ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΠΉ ΡΠ»ΠΎΠΉ (REST-ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ Π·Π°ΡΠΈΡΠ°Π΅Ρ Elasticsearch). ΠΠ°ΠΏΡΠΎΡ DSL Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π½Π°ΡΡΡΠΎΠ΅ΠΊ, Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ΅Π½ ΡΠΎΠΌΡ, ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ Π±Ρ Π΄Π»Ρ Elasticsearch |
ΠΡΠΎΡΡΠΎΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ | Π£ΠΏΡΠΎΡΠ°Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Elasticsearch Ρ ΠΏΠΎΠΌΠΎΡΡΡ GraphQL (ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π½Π°Π½ΠΈΠ΅ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅) | ΠΠ°ΠΏΡΠΎΡΡ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΌ Π΄Π»Ρ Elasticsearch API, Π½ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅/ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ Π΄Π°Π½Π½ΡΡ Π² Elastic Π²ΡΡΡΠΎΠΈΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π»ΠΎΠ³ΠΈΠΊΡ |
Π‘Π»ΠΎΠΆΠ½ΠΎΡΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ | Π‘ΡΠ΅Π΄Π½ΡΡ (ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΡΠ΅ΡΠ²Π΅ΡΠ° Π΄Π»Ρ GraphQL) | Π‘ΡΠ΅Π΄Π½ΡΡ (ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΡΠ΅ΡΠ²Π΅ΡΠ° Π΄Π»Ρ API) |
ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ | ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ Searchkit | ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ReactiveSearch |
ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° Searchkit
ΠΠ°ΠΊ Π΄Π΅Π»Π°ΡΡ Π·Π°ΠΏΡΠΎΡΡ ΠΊ API Searchkit ΠΈ ReactiveSearch
1. ΠΡΠΈΠΌΠ΅Ρ Π·Π°ΠΏΡΠΎΡΠ° Searchkit (GraphQL)
ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ backend Π΄Π»Ρ Searchkit
import { createSearchkitConfig, SearchkitSchema } from "@searchkit/schema";
import { ApolloServer } from "apollo-server";
const searchkitConfig = createSearchkitConfig({
host: "http://localhost:9200", // ΠΠ°Ρ Elasticsearch-ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ
index: "ecommerce", // ΠΠΌΡ ΠΈΠ½Π΄Π΅ΠΊΡΠ° Elasticsearch
hits: {
fields: ["name", "brand.name", "categories.name", "picture"],
},
query: {
fields: ["name", "full_name", "brand.name"],
},
facets: [
{ field: "brand.name.keyword", label: "Brand", type: "terms" },
{ field: "categories.name.keyword", label: "Category", type: "terms" },
],
});
const server = new ApolloServer({
schema: SearchkitSchema(searchkitConfig),
});
server.listen().then(({ url }) => {
console.log(`π Π‘Π΅ΡΠ²Π΅Ρ Π³ΠΎΡΠΎΠ² Π½Π° ${url}`);
});
ΠΡΠΈΠΌΠ΅Ρ GraphQL Π·Π°ΠΏΡΠΎΡΠ°
query SearchProducts($query: String, $filters: [SearchkitFilterSet]) {
results(query: $query, filters: $filters) {
hits {
items {
id
fields {
name
brand {
name
}
categories {
name
}
picture
}
}
}
facets {
id
label
entries {
label
count
id
isSelected
}
}
}
}
ΠΡΠΈΠΌΠ΅Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π·Π°ΠΏΡΠΎΡΠ°
{
"query": "Electrolux",
"filters": [
{
"id": "brand.name.keyword",
"value": "Electrolux"
}
]
}
{
"query": "query SearchProducts($query: String, $filters: [SearchkitFilterSet]) { ... }",
"variables": {
"query": "Electrolux",
"filters": [{ "id": "brand.name.keyword", "value": "Electrolux" }]
}
}
ΠΡΠΈΠΌΠ΅Ρ ΠΎΡΠ²Π΅ΡΠ°
{
"data": {
"results": {
"hits": {
"items": [
{
"id": "32c03957-3738-45a0-b5d5-34cba1cedd6c",
"fields": {
"name": "Π’Π΅ΠΏΠ»ΠΎΠ²Π΅Π½ΡΠΈΠ»ΡΡΠΎΡ Electrolux EFH/C-5115",
"brand": {
"name": "Electrolux"
},
"categories": [
{
"name": "Π’Π΅ΠΏΠ»ΠΎΠ²Π΅Π½ΡΠΈΠ»ΡΡΠΎΡΡ"
}
],
"picture": "https://rkcdn.ru/products/ba10f5f4-7c4a-11e7-9ead-ac162d7b6f40/thumb_big.jpg"
}
}
]
},
"facets": [
{
"id": "brand.name.keyword",
"label": "Brand",
"entries": [
{
"label": "Electrolux",
"count": 100,
"id": "Electrolux",
"isSelected": true
}
]
}
]
}
}
}
ΠΡΠΈΠΌΠ΅Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π° (React Ρ Apollo Client)
ΠΠΈΠΆΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ ΠΏΡΠΎΡΡΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ React, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π·Π°ΠΏΡΠΎΡ ΠΊ GraphQL API Searchkit Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Apollo Client:
import { ApolloClient, InMemoryCache, gql, useQuery } from "@apollo/client";
const client = new ApolloClient({
uri: "http://localhost:4000/graphql", // ΠΠ°Ρ GraphQL ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ Searchkit
cache: new InMemoryCache(),
});
const SEARCH_QUERY = gql`
query SearchProducts($query: String) {
results(query: $query) {
hits {
items {
id
fields {
name
brand {
name
}
picture
}
}
}
}
}
`;
function ProductSearch({ searchQuery }) {
const { loading, error, data } = useQuery(SEARCH_QUERY, {
variables: { query: searchQuery },
client,
});
if (loading) return <p>ΠΠ°Π³ΡΡΠ·ΠΊΠ°...</p>;
if (error) return <p>ΠΡΠΈΠ±ΠΊΠ°: {error.message}</p>;
return (
<div>
{data.results.hits.items.map((item) => (
<div key={item.id}>
<h2>{item.fields.name}</h2>
<p>{item.fields.brand.name}</p>
<img src={item.fields.picture} alt={item.fields.name} />
</div>
))}
</div>
);
}
export default ProductSearch;
2. ΠΡΠΈΠΌΠ΅Ρ Π·Π°ΠΏΡΠΎΡΠ° API ReactiveSearch (REST)
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° API ReactiveSearch
Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Π΄Π»Ρ ΡΠ΅ΡΠ²Π΅ΡΠ° Π½Π° Node.js Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ReactiveSearch API:
const express = require("express");
const { ReactiveSearchApi } = require("@appbaseio/reactivesearch-api");
const app = express();
const api = new ReactiveSearchApi({
host: "http://localhost:9200", // ΠΠ°Ρ Elasticsearch ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ
credentials: "username:password", // ΠΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎ: ΡΡΠ΅ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π΄Π»Ρ Elasticsearch
enableTelemetry: false,
});
// ΠΠΎΠ½ΡΠΈΡΡΠ΅ΠΌ API ReactiveSearch Π½Π° ΠΌΠ°ΡΡΡΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, `/api`
app.use("/api", api.init());
app.listen(4001, () => {
console.log("ReactiveSearch API ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π° http://localhost:4001/api");
});
ΠΡΠΈΠΌΠ΅Ρ REST Π·Π°ΠΏΡΠΎΡΠ°
Π’Π΅ΠΏΠ΅ΡΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ POST-Π·Π°ΠΏΡΠΎΡΡ Π½Π° http://localhost:4001/api/ecommerce/_search
. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "Electrolux",
"fields": ["name", "full_name", "brand.name"]
}
}
],
"filter": [
{
"term": { "brand.name.keyword": "Electrolux" }
}
]
}
}
}
ΠΡΠΈΠΌΠ΅Ρ ΠΎΡΠ²Π΅ΡΠ°
{
"took": 12,
"timed_out": false,
"hits": {
"total": 1,
"max_score": 1.0,
"hits": [
{
"_index": "ecommerce",
"_id": "32c03957-3738-45a0-b5d5-34cba1cedd6c",
"_score": 1.0,
"_source": {
"name": "Π’Π΅ΠΏΠ»ΠΎΠ²Π΅Π½ΡΠΈΠ»ΡΡΠΎΡ Electrolux EFH/C-5115",
"brand": { "name": "Electrolux" },
"categories": [{ "name": "Π’Π΅ΠΏΠ»ΠΎΠ²Π΅Π½ΡΠΈΠ»ΡΡΠΎΡΡ" }],
"picture": "https://rkcdn.ru/products/ba10f5f4-thumb_big.jpg"
}
}
]
}
}
ΠΡΠΈΠΌΠ΅Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π°
ΠΠΈΠΆΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ ΠΏΡΠΎΡΡΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ React, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π·Π°ΠΏΡΠΎΡ ΠΊ API ReactiveSearch Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Axios:
import React, { useState, useEffect } from "react";
import axios from "axios";
function ProductSearch({ searchQuery }) {
const [results, setResults] = useState([]);
useEffect(() => {
axios
.post("http://localhost:4001/api/ecommerce/_search", {
query: {
bool: {
must: [
{
multi_match: {
query: searchQuery,
fields: ["name", "full_name", "brand.name"],
},
},
],
},
},
})
.then((response) => {
setResults(response.data.hits.hits);
})
.catch((error) => {
console.error("ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ Π΄Π°Π½Π½ΡΡ
", error);
});
}, [searchQuery]);
return (
<div>
{results.map((result) => (
<div key={result._id}>
<h2>{result._source.name}</h2>
<p>{result._source.brand.name}</p>
<img src={result._source.picture} alt={result._source.name} />
</div>
))}
</div>
);
}
export default ProductSearch;
3. Π Π΅Π·ΡΠΌΠ΅
-
GraphQL vs. DSL
- ReactiveSearch ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ ΡΡΡΠΎΠΉ Elasticsearch DSL ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π΅Π³ΠΎ Π² ElasticsearchβΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π΄Π΅ΠΉΡΡΠ²ΡΡ ΠΊΠ°ΠΊ ΠΏΡΠΎΡΡΠΎΠΉ ΠΏΡΠΎΠΊΡΠΈ.
- Searchkit, Ρ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ GraphQL-ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ. ΠΠΌΠ΅ΡΡΠΎ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Elasticsearch DSL Π½Π°ΠΏΡΡΠΌΡΡ Π² ES, Π²Ρ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΠ΅ GraphQL Π·Π°ΠΏΡΠΎΡ (Ρ Π²Π°ΡΠΈΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ ΠΏΠΎΠΈΡΠΊΠ° ΠΊΠ°ΠΊ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ). Searchkit Π·Π°ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡ ΡΡΠΎΡ GraphQL Π·Π°ΠΏΡΠΎΡ Π² Elasticsearch DSL.
-
Π‘Π΅ΡΠ²Π΅ΡΠ½Π°Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ
- Π Searchkit Π²Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΠ΅, ΠΊΠ°ΠΊ Π·Π°ΠΏΡΠΎΡΡ ΠΈ ΡΠΈΠ»ΡΡΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΌΠ°ΠΏΠΏΠΈΡΡΡ Π½Π° ΠΏΠΎΠ»Ρ Elasticsearch Π² Π²Π°ΡΠ΅ΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Searchkit.
- ΠΠΎΠ³Π΄Π° ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ Π·Π°ΠΏΡΠΎΡ GraphQL, Searchkit ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π΄Π»Ρ ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΡ ΡΠ΅Π°Π»ΡΠ½ΠΎΠ³ΠΎ DSL Π·Π°ΠΏΡΠΎΡΠ°. ΠΠ±ΡΡΠ½ΠΎ Π²Ρ Π½Π΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΠ΅ ΡΡΡΠΎΠΉ DSL Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π°; ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ ΠΈΠ· GraphQL β DSL ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π²Π½ΡΡΡΠΈ.
-
ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ
- Searchkit ΠΌΠΎΠΆΠ΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΡΠ°ΡΠ΅ΡΡ, ΠΏΠ°Π³ΠΈΠ½Π°ΡΠΈΡ, ΠΌΠ½ΠΎΠ³ΠΎΡΡΠΎΠ²Π½Π΅Π²ΡΠ΅ ΡΠΈΠ»ΡΡΡΡ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΠ΄ΠΎΠ±Π½ΡΠ΅ Π΄Π»Ρ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΠΊΠΎΠΌΠΌΠ΅ΡΡΠΈΠΈ. ΠΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡΡΡ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅ Searchkit.
- GraphQL API ΠΌΠΎΠΆΠ΅Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΡΠΆΠ΅ ΡΡΡΡΠΊΡΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΏΠΎΠΈΡΠΊΠ° ΠΈ Π΄Π°Π½Π½ΡΠ΅ ΡΠ°ΡΠ΅ΡΠΎΠ² Π½Π° Π²Π°Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄.
-
ΠΡΡΡΡΡΡΠ²ΠΈΠ΅ ΠΏΡΡΠΌΠΎΠ³ΠΎ ΡΠ½Π΄ΠΏΠΎΠΈΠ½ΡΠ° DSL
- Searchkit Π½Π΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ Π΄Π»Ρ Π·Π°ΠΏΡΠΎΡΠΎΠ² DSL. ΠΡΠ»ΠΈ Π²Ρ Ρ ΠΎΡΠΈΡΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ DSL Π½Π°ΠΏΡΡΠΌΡΡ, Π²Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ ΡΠ΅ΡΠ²Π΅ΡΠ½ΡΠΉ ΡΠ»ΠΎΠΉ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠ±Ρ ΠΎΠ΄ΠΈΡ ΠΈΠ»ΠΈ ΡΠ°ΡΡΠΈΡΡΠ΅Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ GraphQL Searchkit.
- ΠΠ±Π΅ ΡΠΈΡΡΠ΅ΠΌΡ, ReactiveSearch ΠΈ Searchkit, Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ Π²Π°ΡΠΈΠΌ ΡΡΠΎΠ½ΡΠ΅Π½Π΄ΠΎΠΌ ΠΈ Elasticsearch.
- API ReactiveSearch ΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΊΠ°ΠΊ ΠΏΡΠΎΠΊΡΠΈ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Elasticsearch DSL (Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ).
- Searchkit ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ GraphQL Π°Π±ΡΡΡΠ°ΠΊΡΠΈΡ. ΠΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΠ΅ GraphQL Π·Π°ΠΏΡΠΎΡΡ, ΠΈ ΠΎΠ½ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡ ΠΈΡ Π² DSL β ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π²Ρ Π½Π΅ Π²ΠΈΠ΄ΠΈΡΠ΅ ΠΈ Π½Π΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΠ΅ Elasticsearch DSL Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π°.