> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> مجموعة بيانات تضم أكثر من 28 مليون منشور من Hacker News وتضميناتها المتجهية

# مجموعة بيانات البحث بالمتجهات في Hacker News

<div id="introduction">
  ## مقدمة
</div>

تحتوي [مجموعة بيانات Hacker News](https://news.ycombinator.com/) على 28.74 مليون
منشور وتضميناتها المتجهية. وقد أُنشئت هذه التضمينات باستخدام نموذج [SentenceTransformers](https://sbert.net/)‏ [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2). ويبلغ بُعد كل متجه تضمين `384`.

يمكن استخدام مجموعة البيانات هذه لاستعراض جوانب التصميم وتقدير السعة والأداء لتطبيق
بحث متجهي واسع النطاق وواقعي، مبني على بيانات نصية ينشئها المستخدمون.

<div id="dataset-details">
  ## تفاصيل مجموعة البيانات
</div>

توفّر ClickHouse مجموعة البيانات الكاملة مع التضمينات المتجهية في ملف `Parquet` واحد ضمن [حاوية S3](https://clickhouse-datasets.s3.amazonaws.com/hackernews-miniLM/hackernews_part_1_of_1.parquet)

نوصي المستخدمين أولًا بإجراء تقدير للحجم لتحديد متطلبات التخزين والذاكرة لمجموعة البيانات هذه بالرجوع إلى [الوثائق](/ar/reference/engines/table-engines/mergetree-family/annindexes).

<div id="steps">
  ## خطوات
</div>

<Steps>
  <Step>
    ### إنشاء جدول

    أنشئ جدول `hackernews` لتخزين المنشورات وتضميناتها والسمات المرتبطة بها:

    ```sql theme={null}
    CREATE TABLE hackernews
    (
        `id` Int32,
        `doc_id` Int32,
        `text` String,
        `vector` Array(Float32),
        `node_info` Tuple(
            start Nullable(UInt64),
            end Nullable(UInt64)),
        `metadata` String,
        `type` Enum8('story' = 1, 'comment' = 2, 'poll' = 3, 'pollopt' = 4, 'job' = 5),
        `by` LowCardinality(String),
        `time` DateTime,
        `title` String,
        `post_score` Int32,
        `dead` UInt8,
        `deleted` UInt8,
        `length` UInt32
    )
    ENGINE = MergeTree
    ORDER BY id;
    ```

    إن `id` مجرد عدد صحيح متزايد. ويمكن استخدام السمات الإضافية في عبارات الشرط لفهم
    البحث عن تشابه المتجهات عند دمجه مع التصفية اللاحقة/التصفية المسبقة، كما هو موضح في [الوثائق](/ar/reference/engines/table-engines/mergetree-family/annindexes)
  </Step>

  <Step>
    ### تحميل البيانات

    لتحميل مجموعة البيانات من ملف `Parquet`، نفّذ تعليمة SQL التالية:

    ```sql theme={null}
    INSERT INTO hackernews SELECT * FROM s3('https://clickhouse-datasets.s3.amazonaws.com/hackernews-miniLM/hackernews_part_1_of_1.parquet');
    ```

    سيستغرق إدخال 28.74 مليون صف في الجدول بضع دقائق.
  </Step>

  <Step>
    ### إنشاء فهرس تشابه المتجهات

    شغّل عبارة SQL التالية لتعريف فهرس تشابه المتجهات وإنشائه على العمود `vector` في الجدول `hackernews`:

    ```sql theme={null}
    ALTER TABLE hackernews ADD INDEX vector_index vector TYPE vector_similarity('hnsw', 'cosineDistance', 384, 'bf16', 64, 512);

    ALTER TABLE hackernews MATERIALIZE INDEX vector_index SETTINGS mutations_sync = 2;
    ```

    تَرِد المعلمات واعتبارات الأداء الخاصة بإنشاء الفهرس والبحث في [الوثائق](/ar/reference/engines/table-engines/mergetree-family/annindexes).
    تستخدم العبارة الواردة أعلاه القيمتين 64 و512 على الترتيب للمعاملين الفائقين `M` و`ef_construction` في HNSW.
    تحتاج إلى اختيار القيم المثلى لهذه المعلمات بعناية، وذلك من خلال تقييم وقت بناء الفهرس وجودة نتائج البحث
    المرتبطة بالقيم المحددة.

    قد يستغرق بناء الفهرس وحفظه بضع دقائق، أو حتى ساعة، لمجموعة البيانات الكاملة التي تضم 28.74 مليونًا، وذلك حسب عدد أنوية CPU المتاحة ومعدل نقل وحدة التخزين.
  </Step>

  <Step>
    ### إجراء بحث ANN

    بعد إنشاء فهرس تشابه المتجهات، ستستخدم استعلامات البحث المتجهي هذا الفهرس تلقائيًا:

    ```sql title="Query" theme={null}
    SELECT id, title, text
    FROM hackernews
    ORDER BY cosineDistance( vector, <search vector>)
    LIMIT 10

    ```

    قد يستغرق تحميل الفهرس المتجهي إلى الذاكرة لأول مرة بضع ثوانٍ/دقائق.
  </Step>

  <Step>
    ### توليد تضمينات لاستعلام البحث

    توفر [Sentence Transformers](https://www.sbert.net/) نماذج تضمين محلية وسهلة الاستخدام لاستخلاص المعنى الدلالي للجمل والفقرات.

    تحتوي مجموعة البيانات الخاصة بـ HackerNews على تضمينات متجهية مُولَّدة باستخدام نموذج
    [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2).

    يُقدَّم فيما يلي مثال على سكريبت بايثون يوضح كيفية توليد متجهات التضمين برمجيًا باستخدام حزمة بايثون `sentence_transformers`. يُمرَّر بعد ذلك متجه تضمين البحث وسيطًا إلى دالة [`cosineDistance()`](/ar/reference/functions/regular-functions/distance-functions#cosineDistance) في الاستعلام \`SELECT\`.

    ```python theme={null}
    from sentence_transformers import SentenceTransformer
    import sys

    import clickhouse_connect

    print("Initializing...")

    model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

    chclient = clickhouse_connect.get_client() # ClickHouse credentials here

    while True:
        # Take the search query from user
        print("Enter a search query :")
        input_query = sys.stdin.readline();
        texts = [input_query]

        # Run the model and obtain search vector
        print("Generating the embedding for ", input_query);
        embeddings = model.encode(texts)

        print("Querying ClickHouse...")
        params = {'v1':list(embeddings[0]), 'v2':20}
        result = chclient.query("SELECT id, title, text FROM hackernews ORDER BY cosineDistance(vector, %(v1)s) LIMIT %(v2)s", parameters=params)
        print("Results :")
        for row in result.result_rows:
            print(row[0], row[2][:100])
            print("---------")

    ```

    يظهر أدناه مثال على تشغيل نص بايثون البرمجي أعلاه ونتائج بحث التشابه
    (يُطبع 100 حرف فقط من كل منشور من أعلى 20 منشورًا):

    ```text theme={null}
    Initializing...

    Enter a search query :
    Are OLAP cubes useful

    Generating the embedding for  "Are OLAP cubes useful"

    Querying ClickHouse...

    Results :

    27742647 smartmic:
    slt2021: OLAP Cube is not dead, as long as you use some form of:<p>1. GROUP BY multiple fi
    ---------
    27744260 georgewfraser:A data mart is a logical organization of data to help humans understand the schema. Wh
    ---------
    27761434 mwexler:&quot;We model data according to rigorous frameworks like Kimball or Inmon because we must r
    ---------
    28401230 chotmat:
    erosenbe0: OLAP database is just a copy, replica, or archive of data with a schema designe
    ---------
    22198879 Merick:+1 for Apache Kylin, it&#x27;s a great project and awesome open source community. If anyone i
    ---------
    27741776 crazydoggers:I always felt the value of an OLAP cube was uncovering questions you may not know to as
    ---------
    22189480 shadowsun7:
    _Codemonkeyism: After maintaining an OLAP cube system for some years, I&#x27;m not that
    ---------
    27742029 smartmic:
    gengstrand: My first exposure to OLAP was on a team developing a front end to Essbase that
    ---------
    22364133 irfansharif:
    simo7: I&#x27;m wondering how this technology could work for OLAP cubes.<p>An OLAP cube
    ---------
    23292746 scoresmoke:When I was developing my pet project for Web analytics (<a href="https:&#x2F;&#x2F;github
    ---------
    22198891 js8:It seems that the article makes a categorical error, arguing that OLAP cubes were replaced by co
    ---------
    28421602 chotmat:
    7thaccount: Is there any advantage to OLAP cube over plain SQL (large historical database r
    ---------
    22195444 shadowsun7:
    lkcubing: Thanks for sharing. Interesting write up.<p>While this article accurately capt
    ---------
    22198040 lkcubing:Thanks for sharing. Interesting write up.<p>While this article accurately captures the issu
    ---------
    3973185 stefanu:
    sgt: Interesting idea. Ofcourse, OLAP isn't just about the underlying cubes and dimensions,
    ---------
    22190903 shadowsun7:
    js8: It seems that the article makes a categorical error, arguing that OLAP cubes were r
    ---------
    28422241 sradman:OLAP Cubes have been disrupted by Column Stores. Unless you are interested in the history of
    ---------
    28421480 chotmat:
    sradman: OLAP Cubes have been disrupted by Column Stores. Unless you are interested in the
    ---------
    27742515 BadInformatics:
    quantified: OP posts with inverted condition: “OLAP != OLAP Cube” is the actual titl
    ---------
    28422935 chotmat:
    rstuart4133: I remember hearing about OLAP cubes donkey&#x27;s years ago (probably not far
    ---------
    ```

    ## تطبيق تجريبي للتلخيص

    يوضح المثال أعلاه البحث الدلالي واسترداد المستندات باستخدام ClickHouse.

    فيما يلي مثال على تطبيق بسيط للغاية ولكنه واعد في مجال الذكاء الاصطناعي التوليدي.

    يُنفّذ التطبيق الخطوات التالية:

    1. يستقبل *موضوعًا* كمدخل من المستخدم
    2. يُنشئ متجه تضمين للـ *موضوع* باستخدام `SentenceTransformers` مع النموذج `all-MiniLM-L6-v2`
    3. يسترجع منشورات/تعليقات وثيقة الصلة باستخدام البحث بالتشابه المتجهي على الجدول `hackernews`
    4. يستخدم `LangChain` وواجهة Chat API من OpenAI للنموذج `gpt-3.5-turbo` **لتلخيص** المحتوى المسترجع في الخطوة رقم 3.
       وتُمرَّر المنشورات/التعليقات المسترجعة في الخطوة رقم 3 على أنها *سياق* إلى Chat API، وهي حلقة الوصل الأساسية في Generative AI.

    يُعرض أدناه أولاً مثال على تشغيل تطبيق التلخيص، يليه الكود الخاص بهذا التطبيق. يتطلب تشغيل التطبيق ضبط مفتاح OpenAI API في متغير البيئة `OPENAI_API_KEY`. يمكن الحصول على مفتاح OpenAI API بعد التسجيل في [https://platform.openai.com](https://platform.openai.com).

    يُوضّح هذا التطبيق حالة استخدام للذكاء الاصطناعي التوليدي (Generative AI) قابلة للتطبيق في مجالات مؤسسية متعددة، منها:
    تحليل مشاعر العملاء، وأتمتة الدعم الفني، واستخراج المعلومات من محادثات المستخدمين، والوثائق القانونية، والسجلات الطبية،
    ومحاضر الاجتماعات، والبيانات المالية، وغير ذلك.

    ```shell theme={null}
    $ python3 summarize.py

    Enter a search topic :
    ClickHouse performance experiences

    Generating the embedding for ---->  ClickHouse performance experiences

    Querying ClickHouse to retrieve relevant articles...

    Initializing chatgpt-3.5-turbo model...

    Summarizing search results retrieved from ClickHouse...

    Summary from chatgpt-3.5:
    The discussion focuses on comparing ClickHouse with various databases like TimescaleDB, Apache Spark,
    AWS Redshift, and QuestDB, highlighting ClickHouse's cost-efficient high performance and suitability
    for analytical applications. Users praise ClickHouse for its simplicity, speed, and resource efficiency
    in handling large-scale analytics workloads, although some challenges like DMLs and difficulty in backups
    are mentioned. ClickHouse is recognized for its real-time aggregate computation capabilities and solid
    engineering, with comparisons made to other databases like Druid and MemSQL. Overall, ClickHouse is seen
    as a powerful tool for real-time data processing, analytics, and handling large volumes of data
    efficiently, gaining popularity for its impressive performance and cost-effectiveness.
    ```

    كود التطبيق المذكور أعلاه:

    ```python theme={null}
    print("Initializing...")

    import sys
    import json
    import time
    from sentence_transformers import SentenceTransformer

    import clickhouse_connect

    from langchain.docstore.document import Document
    from langchain.text_splitter import CharacterTextSplitter
    from langchain.chat_models import ChatOpenAI
    from langchain.prompts import PromptTemplate
    from langchain.chains.summarize import load_summarize_chain
    import textwrap
    import tiktoken

    def num_tokens_from_string(string: str, encoding_name: str) -> int:
        encoding = tiktoken.encoding_for_model(encoding_name)
        num_tokens = len(encoding.encode(string))
        return num_tokens

    model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

    chclient = clickhouse_connect.get_client(compress=False) # ClickHouse credentials here

    while True:
        # Take the search query from user
        print("Enter a search topic :")
        input_query = sys.stdin.readline();
        texts = [input_query]

        # Run the model and obtain search or reference vector
        print("Generating the embedding for ----> ", input_query);
        embeddings = model.encode(texts)

        print("Querying ClickHouse...")
        params = {'v1':list(embeddings[0]), 'v2':100}
        result = chclient.query("SELECT id,title,text FROM hackernews ORDER BY cosineDistance(vector, %(v1)s) LIMIT %(v2)s", parameters=params)

        # Just join all the search results
        doc_results = ""
        for row in result.result_rows:
            doc_results = doc_results + "\n" + row[2]

        print("Initializing chatgpt-3.5-turbo model")
        model_name = "gpt-3.5-turbo"

        text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
            model_name=model_name
        )

        texts = text_splitter.split_text(doc_results)

        docs = [Document(page_content=t) for t in texts]

        llm = ChatOpenAI(temperature=0, model_name=model_name)

        prompt_template = """
    Write a concise summary of the following in not more than 10 sentences:

    {text}

    CONSCISE SUMMARY :
    """

        prompt = PromptTemplate(template=prompt_template, input_variables=["text"])

        num_tokens = num_tokens_from_string(doc_results, model_name)

        gpt_35_turbo_max_tokens = 4096
        verbose = False

        print("Summarizing search results retrieved from ClickHouse...")

        if num_tokens <= gpt_35_turbo_max_tokens:
            chain = load_summarize_chain(llm, chain_type="stuff", prompt=prompt, verbose=verbose)
        else:
            chain = load_summarize_chain(llm, chain_type="map_reduce", map_prompt=prompt, combine_prompt=prompt, verbose=verbose)

        summary = chain.run(docs)

        print(f"Summary from chatgpt-3.5: {summary}")
    ```
  </Step>
</Steps>
