Үйлчилгээний системийн архитектурд, гарын авлага HTTP API-ийн болон реляцийн мэдээллийн сангийн тархины хооронд синхронизацийн хязгаар нь байнгын инженерийн асуултуудтай байдаг — ялангуяа API-ийн асуултууд нь нарийн транзакцийн хэлбэрээр хязгаарлагдмал, гүнзгий нэхмэл JSON-ийн ачаалалтай ачаалалтай байдаг (комментийн нэхмэл, аж ахуйн нэгжийн түлхүүр, олон түвшний BOM бүтэц). CocoIndex-ийн Custom Source Abstraction нь нарийн HTTP/gRPC-ийн эцэстын түвшний түвшний түвшний түвшний түвшний түвшний түвшний түвшний түвшний түвшний түвшний түвшний тү • Stateless API→Stateful Stream трансформац: REST GET асуултуудыг append-log семантикинд конвертирууд • Cycle Detection нь Recursive Tree Traversal: Хязгааргүй нарийвчлалтай тайлбар DAGs (Directed Acyclic Graphs) -ийг хязгааргүй хязгааргүй хязгааргүй • Schema evolution дэмжлэг: Structural subtyping ашиглан forward compatibility нь Python-д өгөгдлийн ангиллын суурилсан хэвлэх • Postgres Sink Connector Integration: Psycopg3 async холболтын багцуулах + COPY протокол нь тоног төхөөрөмжийн багцуулах • GIN-индекстэй бүрэн текст хайлтын тохиргоог: Англи хэлний хэлбэрээр хэлбэрээр хэлбэрээр хэлбэрээр цуглуулах + Ranking функцийг материалах Энэ жишээ нь, бид HackerNews-ийн хувьд өөрчилсөн холбогч бий болгосон. Энэ нь сүүлийн үеийн түүхүүд + нэшсэн сэтгэгдэл олж, тэднийг индекс, Postgres-ийн бүрэн текст хайлтын дэмжлэгтэй хялбар хайлтын интерфэйс харуулдаг. Ямар ч өөрчилсөн эх сурвалж ашиглах вэ? Олон үзэсгэлэнд, хоолой нь зүгээр л цэвэр ширээсийг унших биш юм. Тэд: Үнэгүй REST үйлчилгээ Ажиллагч APIs Эрүүл мэндийн систем Нестандарт өгөгдлийн загварууд, уламжлалт холбогчд тохиромжтой биш CocoIndex-ийн Custom Source API нь эдгээр интеграцийг үүсгэдэг Үнэндээ ad-hoc скрипт бичнэ үү, Та API-ийг "суурь бүрэлдэхүүн хэсэг" гэж хавтан, CocoIndex энэ нь одоогоор олж авах болно. Үнэлгээ Project Walkthrough — HackerNews индекс бий болгох Эдүүлбэр ХакерNews хайлтын API Тавтай морилно уу Comments Бүтээгдэхүүнийг шинэчлэх нь зөвхөн өөрчлөгдсөн тэсвэртэй Big Content in Postgres Текст хайлтын интерфэйс илрүүлэх CocoIndex автоматаар өөрчилсөн олборлолт, idempotency, lineage, станц синхрон хийх болно. Үзүүлэлт Газрын галт тэрэг нь гурван гол хэсэг юм: Define a custom source ( ) HackerNewsConnector Calls HackerNews API Emits rows for changed/updated threads Pulls full thread + comment tree Build an index with CocoIndex Flow Collect thread content Collect all comments recursively Export to a Postgres table ( ) hn_messages Add a lightweight query handler Uses PostgreSQL full-text search Returns ranked matches for a keyword query Бүх зөвхөн үйл явцыг HN утас өөрчлөгдсөн бөгөөд бүх зүйлийг синхронизолдаг. cocoindex update Зохиогчийн эрх © Open Source . GitHub нь Баримтлал if you don't have one. Install Postgres Data Model тодорхойлолт Бүх өөрчлөн эх үүсвэр нь хоёр хялбар өгөгдлийн төрөл тодорхойлох: Key Type → uniquely identifies an item Value Type → Энэ зүйлсийн бүрэн агуулгыг Hacker News-д, бүх мэдээ нь нунтаг юм, бүх нунтаг нь хэд хэдэн санал болгож болно. HackerNews-ийн хувьд, харин үүнийг тодорхойлохын тулд: class _HackerNewsThreadKey(NamedTuple): """Row key type for HackerNews source.""" thread_id: str Key нь байх ёстой: Хашаа Үнэлгээ тогтвортой (чанарын хооронд өөрчилжгүй) Үнэгүй өгөгдлийн цуврал нь үнэ цэнэтэй: @dataclasses.dataclass class _HackerNewsComment: id: str author: str | None text: str | None created_at: datetime | None @dataclasses.dataclass class _HackerNewsThread: """Value type for HackerNews source.""" author: str | None text: str url: str | None created_at: datetime | None comments: list[_HackerNewsComment] Энэ нь CocoIndex-ийг бүрэн олж авсан үед HackerNews-ийн "эмийг" юу гэж хэлдэг. Ажлын дараагийн бичлэг, түүний нийтлэл, Бүх нэг удаа үзсэн comments. _HackerNewsThread _HackerNewsComment Custom Source Connector бий болгох A Custom Source has two parts: SourceSpec — deklarative конфигураци SourceConnector — өгөгдлийн унших үйл ажиллагааны логик Зохиогчийн эрх SourceSpec А in CocoIndex нь системийг хэлдэг deklarative конфигурац юм. Нөхцөл эх үүсвэр дээр. Энэ нь самд өгөгдлийг олж чадахгүй - энэ нь эх үүсвэр холбогчээр ажиллуулж байна. SourceSpec what data to fetch how to connect class HackerNewsSource(SourceSpec): """Source spec for HackerNews API.""" tag: str | None = None max_results: int = 100 Байрлал: tag Optional filter for the type of HackerNews content. Example: , , . "story" "job" "poll" If , it fetches all types. None max_results Maximum number of threads to fetch from HackerNews at a time. Helps limit the size of the index for performance or testing. Connector тодорхойлолт Connector-ийн конфигураци, HTTP сессийг тохируулахын тулд HackerNews-ийн өгөгдлийг үр ашигтай олж болно. @source_connector( spec_cls=HackerNewsSource, key_type=_HackerNewsThreadKey, value_type=_HackerNewsThread, ) class HackerNewsConnector: """Custom source connector for HackerNews API.""" _spec: HackerNewsSource _session: aiohttp.ClientSession def __init__(self, spec: HackerNewsSource, session: aiohttp.ClientSession): self._spec = spec self._session = session @staticmethod async def create(spec: HackerNewsSource) -> "HackerNewsConnector": """Create a HackerNews connector from the spec.""" return HackerNewsConnector(spec, aiohttp.ClientSession()) tells CocoIndex that this class is a . It specifies: source_connector custom source connector : the configuration class ( ) spec_cls HackerNewsSource : how individual items are identified ( ) key_type _HackerNewsThreadKey : the structure of the data returned ( ) value_type _HackerNewsThread Create() нь CocoIndex-ийн Connector-ийг эхлэхэд нэрлэдэг бөгөөд энэ нь HTTP хүсэл хийхэд шинэ aiohttp.ClientSession-ийг үүсгэдэг. Хадгаламжийн Threads Нөхцөл Метод Энэ нь Тавтай морилно уу, Тавтай морилно уу, Тавтай морилно уу Энэ нь өөрчилсөн байж болох юм. list() HackerNewsConnector discovering all available HackerNews threads know which threads exist async def list( self, ) -> AsyncIterator[PartialSourceRow[_HackerNewsThreadKey, _HackerNewsThread]]: """List HackerNews threads using the search API.""" # Use HackerNews search API search_url = "https://hn.algolia.com/api/v1/search_by_date" params: dict[str, Any] = {"hitsPerPage": self._spec.max_results} if self._spec.tag: params["tags"] = self._spec.tag async with self._session.get(search_url, params=params) as response: response.raise_for_status() data = await response.json() for hit in data.get("hits", []): if thread_id := hit.get("objectID", None): utime = hit.get("updated_at") ordinal = ( int(datetime.fromisoformat(utime).timestamp()) if utime else NO_ORDINAL ) yield PartialSourceRow( key=_HackerNewsThreadKey(thread_id=thread_id), data=PartialSourceRowData(ordinal=ordinal), ) Үнэгүй . list() metadata for all recent HackerNews threads For each thread: It generates a with: PartialSourceRow : the thread ID key : the last updated timestamp ordinal Загвар: CocoIndex нь бүрэн нунтаг агуулгыг олж авахгүйгээр ямар ч нунтаг байдаг, ямар ч өөрчилсөн дараах боломжийг олгодог. Хэвлэх Full Thread Content Энэ async арга нь а (Хэрэгсэл нь) нь , and wraps the result in a Object — CocoIndex нь цуврал түвшинд хэрэглэдэг бүтэц. single HackerNews thread API PartialSourceRowData async def get_value( self, key: _HackerNewsThreadKey ) -> PartialSourceRowData[_HackerNewsThread]: """Get a specific HackerNews thread by ID using the items API.""" # Use HackerNews items API to get full thread with comments item_url = f"https://hn.algolia.com/api/v1/items/{key.thread_id}" async with self._session.get(item_url) as response: response.raise_for_status() data = await response.json() if not data: return PartialSourceRowData( value=NON_EXISTENCE, ordinal=NO_ORDINAL, content_version_fp=None, ) return PartialSourceRowData( value=HackerNewsConnector._parse_hackernews_thread(data) ) get_value() -ийг санал болгож байна. get_value() -ийг санал болгож байна. get_value() -ийг хүлээн авах болно. Хөргөлтийн JSON-ийг структурын Python объектонд (_HackerNewsThread + _HackerNewsComment) хуваалцах. Өнгөрсөн утас агуулсан PartialSourceRowData returns. Өнгөрсөн дэмжлэг CocoIndex нь энэ эх үүсвэр нь цаг хугацааны тэмдэг (ординал) санал болгож байна. def provides_ordinal(self) -> bool: return True CocoIndex ординал хэрэглэдэг нь зөвхөн өөрчлөгдсөн нунтаг шинэчлэх, үр дүнтэй сайжруулах. Parsing JSON into Structured Data Энэ статик арга нь JSON-ийн зэвэрдэггүй хариултыг Энэ нь normalized Бүтээгдэхүүнийг агуулсан: API _HackerNewsThread Сэтгэгдэл (Title, Text, Metadata) Бүх үзүүлэлтүүд, нэг жагсаалттай Сайн Python Datetime Objects Энэ нь а Сэтгэгдэл үлдээх recursive traversal @staticmethod def _parse_hackernews_thread(data: dict[str, Any]) -> _HackerNewsThread: comments: list[_HackerNewsComment] = [] def _add_comments(parent: dict[str, Any]) -> None: children = parent.get("children", None) if not children: return for child in children: ctime = child.get("created_at") if comment_id := child.get("id", None): comments.append( _HackerNewsComment( id=str(comment_id), author=child.get("author", ""), text=child.get("text", ""), created_at=datetime.fromisoformat(ctime) if ctime else None, ) ) _add_comments(child) _add_comments(data) ctime = data.get("created_at") text = data.get("title", "") if more_text := data.get("text", None): text += "\n\n" + more_text return _HackerNewsThread( author=data.get("author"), text=text, url=data.get("url"), created_at=datetime.fromisoformat(ctime) if ctime else None, comments=comments, ) Хавтгай HackerNews API-ийг _HackerNewsThread болон _HackerNewsComment-д хувиргадаг. _add_comments() recursively нэгийг харахын тулд санал болгож байна. Түлхүүр үгс + текст нь гол тэсвэртэй агуулгыг нэгтгэсэн. Produces a fully structured object ready for indexing. Бүгдийг нэгтгэх Flow Таны дамжуулалт одоо React компонент шиг унших болно. Гэрэлтүүлэг тодорхойлолт, эх үүсвэрийг холбох @cocoindex.flow_def(name="HackerNewsIndex") def hackernews_flow( flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope ) -> None: # Add the custom source to the flow data_scope["threads"] = flow_builder.add_source( HackerNewsSource(tag="story", max_results=500), refresh_interval=timedelta(minutes=1), ) # Create collectors for different types of searchable content message_index = data_scope.add_collector() Бүх ширээг боловсруулах, структурын мэдээлэл цуглуулах with data_scope["threads"].row() as thread: # Index the main thread content message_index.collect( id=thread["thread_id"], thread_id=thread["thread_id"], content_type="thread", author=thread["author"], text=thread["text"], url=thread["url"], created_at=thread["created_at"], ) Нөхцөл бүрийг боловсруулах, бүтэцтэй мэдээлэл цуглуулах with thread["comments"].row() as comment: message_index.collect( id=comment["id"], thread_id=thread["thread_id"], content_type="comment", author=comment["author"], text=comment["text"], created_at=comment["created_at"], ) Үйлчилгээний баглаа боодол руу экспортын message_index.export( "hn_messages", cocoindex.targets.Postgres(), primary_key_fields=["id"], ) CocoIndex now: polls the HackerNews API Түлхүүр үгс өөрчилж flattens nested comments Postgres руу экспортлогч Live Mode дэмжлэг Таны апп нь одоо тогтмол цаг хугацааны хайлтын индекс болгон хайж болно. HackerNews Index-ийг хайх & хайх Эдгээр үед та индекс дамжуулалтай байдаг. Дараагийн үйл явцад та анхаарал хандах үйлчлүүлэгчид тодорхойлох боломжтой. Та CocoInsight-д анхаараг ажиллуулах боломжтой. Та анхаараг ажиллуулахын тулд таны сонгодог ямар ч библиотек, рамкийг ашиглаж болно. . Хэрэглэгчийн @hackernews_flow.query_handler() def search_text(query: str) -> cocoindex.QueryOutput: """Search HackerNews threads by title and content.""" table_name = cocoindex.utils.get_target_default_name(hackernews_flow, "hn_messages") with connection_pool().connection() as conn: with conn.cursor() as cur: # Simple text search using PostgreSQL's text search capabilities cur.execute( f""" SELECT id, thread_id, author, content_type, text, created_at, ts_rank(to_tsvector('english', text), plainto_tsquery('english', %s)) as rank FROM {table_name} WHERE to_tsvector('english', text) @@ plainto_tsquery('english', %s) ORDER BY rank DESC, created_at DESC """, (query, query), ) results = [] for row in cur.fetchall(): results.append( { "id": row[0], "thread_id": row[1], "author": row[2], "content_type": row[3], "text": row[4], "created_at": row[5].isoformat(), } ) return cocoindex.QueryOutput(results=results) Энэ код нь хакердсан хакердсан мэдээг хайж буй хакердсан мэдээг хайж буй хакердсан мэдээг хайж буй хакердсан өгөгдлийн жагсаалт, дараа нь PostgreSQL-ийн бүрэн текст хайлт ашигладаг ( and ) анхааралтай шугам олохын тулд. to_tsvector plainto_tsquery Бүтээгдэхүүний үр дүн нь ач холбогдолтой ( ) and creation time, formatted into dictionaries, and returned as a structured . Essentially, it performs a full-text search over the indexed content and delivers ranked, structured results. ts_rank cocoindex.QueryOutput Таны HackerNews Custom эх сурвалж Once your custom source and flow are ready, running it with CocoIndex is straightforward. You can either or HackerNews тухай update the index on-demand keep it continuously in sync 1. Install Dependencies Та Python суулгах, дараа нь редактируулсан загвар дээр өөрийн төсөл суулгах: pip install -e . Энэ нь CocoIndex-ийг бүх шаардлагыг хамт суулгахын тулд холбогч шинэчлэхгүйгээр хөгжүүлэх, шинэчлэх боломжийг олгодог. 2. Update the Target (On-Demand) Хамгийн сүүлийн үеийн HackerNews тэсвэртэй таны зорилго (жишээ нь, Postgres): cocoindex update main Only threads that will be re-processed. have changed Таны зорилго нь хамгийн сүүлийн үеийн 500 HackerNews нунтагтай синхронизолтай байх болно. Ажлын шинэчлэлтүүд нь үр дүнтэй цаг хугацаа, компьютерийн ресурс хэмнэх болно. Хамгийн сүүлийн үеийн хакердсан 500 хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан хакердсан cocoindex update -L main Жишээ нь, HackerNews-ийг байнга харуулсан. CocoIndex automatically handles incremental changes and keeps the target synchronized. Тавцан, хайлтын, AI-ийн хоолой хийхэд тохиромжтой бөгөөд энэ нь бодит цаг хугацааны өгөгдлийг шаарддаг. 3. Troubleshoot & Inspect with CocoInsight CocoInsight lets you , see the lineage of your data, and understand what’s happening under the hood. visualize and debug your flow Start the server: cocoindex server -ci main Then open the UI in your browser: https://cocoindex.io/cocoinsight CocoInsight нь нунтаг өгөгдлийн хадгалах боломжийг олгодог - энэ нь локал дээр таны дамжуулалтыг буцаж, шалгахын тулд аюулгүй юм. CocoInsight has zero pipeline data retention — it’s safe for debugging and inspecting your flows locally. Энэ нь Өмнөх шатанд QueryHandler суулгах хэрэгтэй. What You Can Build Next Эдгээр хялбар жишээ нь ихэнх илүү их ширээг нээж: Trending-topic детектор бий болгох Албан ёслолтууд дээр LLM хуваалцах хоолойг ажиллуулах Тавтай морилно уу + Vector Search Mirror HN into your internal data warehouse Build a real-time HN dashboard Extend to other news sources (Reddit, Lobsters, etc.) Учир нь бүх хоолой declarative болон incremental юм, энэ нь хялбар байна. Түүнээс гадна Custom Sources нь та Python логик нь нэмэлт өгөгдлийн тоос, хамгийн сайн хэрэглээний тохиолдолд ихэвчлэн өгөгдлийн систем нь стандарт мэдээллийн сан конекторуудтай, энгийн хавтантай, эсвэл ихэвчлэн урьдчилан боловсруулах шаарддаг. Бүртгүүлэх "Hard-to-Reach" The Knowledge Aggregator for LLM Context AI bot-ийн контекст хөдөлгүүрийн үүсгэх нь ихэвчлэн стандартгүй документын эх сурвалжаас зайлсхийх хэрэгтэй. Компьютерийн (Data Stitching) Бүх компаниуд нь хэрэглэгчийн өгөгдлийг олон микросервисын хооронд хамарсан байдаг. Та өгөгдөл таны индексд харах өмнө "виртуал хоосон" гэж ажилладаг өөрчилсөн эх үүсвэр бий болгох боломжтой. For example the Source: Auth үйлчилгээ (Okta/Auth0) нь хэрэглэгчийн ID-ийг олж авах. Uses that ID to fetch billing status from . Stripe API Энэ ID-ийг Internal Redis-ийн хэрэглээний логтыг олж авахын тулд ашигладаг. Комплекс ETL-ийг downstream-ийг удирдах нь өөрчилсөн эх үүсвэрийг нэг object. CocoIndex tracks the state of this composite object; if the user upgrades in Stripe changes their email in Auth0, the index updates automatically. User360 or The "Legacy Wrapper" (Modernization Layer) Компаниуд нь хэзээ ч анхааралтай системийг (SOAP, XML, Mainframes) хамарсан үнэ цэнэтэй өгөгдөлтэй байдаг. Та 20-ийн жилийн оюутны систем дээр орчин үеийн, анхааралтай SQL интерфэйс (CocoIndex тархины дамжуулан) олж авах болно. Public Data Monitor (Конкурентын мэдлэг) Webhooks-ийг санал болгожгүй албан ёсны вэбсайтууд эсвэл API-д өөрчлөлтийг харах. The Source: Scraping e-commerce product pages. Competitor Pricing: Polling a government RSS feed or FDA drug approval database. Regulatory Feeds: Hitting a CoinGecko or Yahoo Finance API. Crypto/Stocks: ашиглах capabilities, you can trigger downstream alerts only when a price changes by >5% or a new regulation is posted, rather than spamming your database with identical polling results. The CocoIndex Value: diff Хэрэв энэ нь чухал Custom Sources Энэ загвар нь API — дотоод, гадаадын, эртний, эсвэл бодит цаг. Бүртгүүлэх Энэ нь хялбар, харин хүчтэй загварыг илрүүлэх болно: Хэрэв та үүнийг олж авах боломжтой бол CocoIndex үүнийг индекс, үүнийг дифф, үүнийг синхронизож болно. If you can fetch it, CocoIndex can index it, diff it, and sync it. Хэрэв та HackerNews-ийг индексируулна уу, эсвэл аж ахуйн нэгжийн үйлчилгээний долоо хоногт оркестрируулдаг уу, бүтэц нь танд тогтвортой хавтгайтай байдаг: Насанд хүрэгчдийн Детерминист шинэчлэл Автомат Lineage Гүйцэтгэх экспорт Минималтай инфраструктур overhead Try It, Fork It, Star It Хэрэв та энэ нь тусалдаг бол, a Энэ нь бусад хүмүүст CocoIndex-ийг олж авахын тулд туслах, дэлгэрэнгүй хөгжлийн дэмждэг. star on GitHub GitHub нь