JSON-LINQ

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


    Tests:
    - t/0009-concurrent-fh.t: new test (21 tests) covering concurrent
      From* in Join, GroupJoin, Concat+Join, and To* round-trip.

1.01  2026-05-03 JST (Japan Standard Time)

    LTSV interoperability.

    Features:
    - FromLTSV($file)         : read LTSV file (streaming, one line at a time)
                                ported from LTSV::LINQ 1.08
    - ToLTSV($file)           : write sequence as LTSV file (streaming)
                                ported from LTSV::LINQ 1.08
    - Method count: 63 -> 65
    - POD additions:
      * "LTSV Interoperability" subsection under METHODS
      * "JOIN: JSON (main) with LTSV (sub-table)" example
      * "JOIN: LTSV (main) with JSON (sub-table)" example
      * Updated DIAGNOSTICS to cover FromLTSV/ToLTSV file errors
      * Updated ARCHITECTURE / Memory Characteristics
    - Documentation:
      * 21-language cheat sheets updated with FromLTSV/ToLTSV and the

Changes  view on Meta::CPAN

      These prevent regressions of the same class.

    No external dependencies added.  Pure Perl, Perl 5.005_03+ compatible.

1.00  2026-04-20 JST (Japan Standard Time)

    Initial release.

    Features:
    - FromJSON($file)         : read JSON file (top-level array or object)
    - FromJSONL($file)        : read JSONL file (streaming, one line at a time)
    - FromJSONString($json)   : read JSON string (array or object)
    - ToJSON($file)           : write sequence as JSON array file
    - ToJSONL($file)          : write sequence as JSONL file
    - true / false            : JSON boolean singleton objects
    - Built-in JSON encoder/decoder (derived from mb::JSON 0.06)
      No CPAN JSON module required.
    - 60 LINQ methods from LTSV::LINQ 1.08:
      From, Range, Empty, Repeat,
      Where (with DSL), Select, SelectMany, Concat, Zip,
      Take, Skip, TakeWhile, SkipWhile,

README  view on Meta::CPAN

SYNOPSIS
        use JSON::LINQ;

        # Read JSON file (array of objects) and query
        my @results = JSON::LINQ->FromJSON("users.json")
            ->Where(sub { $_[0]{age} >= 18 })
            ->Select(sub { $_[0]{name} })
            ->Distinct()
            ->ToArray();

        # Read JSONL (JSON Lines) file - streaming, one object per line
        my @errors = JSON::LINQ->FromJSONL("events.jsonl")
            ->Where(sub { $_[0]{level} eq 'ERROR' })
            ->ToArray();

        # Read LTSV (Labeled Tab-Separated Values) file - streaming
        my @rows = JSON::LINQ->FromLTSV("access.ltsv")
            ->Where(sub { $_[0]{status} eq '200' })
            ->ToArray();

        # DSL syntax for simple filtering
        my @active = JSON::LINQ->FromJSON("users.json")
            ->Where(status => 'active')
            ->ToArray();

        # Grouping and aggregation

README  view on Meta::CPAN

            })
            ->OrderByDescending(sub { $_[0]{Total} })
            ->ToArray();

        # Write results back as JSON, JSONL, LTSV, or CSV
        JSON::LINQ->From(\@results)->ToJSON("output.json");
        JSON::LINQ->From(\@results)->ToJSONL("output.jsonl");
        JSON::LINQ->From(\@results)->ToLTSV("output.ltsv");
        JSON::LINQ->From(\@results)->ToCSV("output.csv");

        # Read CSV (Comma-Separated Values) file - streaming
        my @rows = JSON::LINQ->FromCSV("access.csv")
            ->Where(sub { $_[0]{status} eq '200' })
            ->ToArray();

        # CSV with options
        my $q = JSON::LINQ->FromCSV("data.tsv", sep => "\t");
        my $q = JSON::LINQ->FromCSV("noheader.csv",
            headers => [qw(name age city)]);

        # Write CSV with column order control

README  view on Meta::CPAN


DESCRIPTION
    JSON::LINQ provides a LINQ-style query interface for JSON, JSONL
    (JSON Lines), LTSV (Labeled Tab-Separated Values), and CSV
    (Comma-Separated Values) files.  It is the JSON counterpart of
    LTSV::LINQ, sharing the same LINQ API and adding JSON, LTSV, and
    CSV I/O methods.

    Key features:

    * Lazy evaluation - O(1) memory for JSONL, LTSV, and CSV streaming
    * Method chaining - Fluent, readable query composition
    * DSL syntax - Simple key-value filtering without code references
    * 67 LINQ methods - including JSON I/O (FromJSON, FromJSONL,
      FromJSONString, ToJSON, ToJSONL), LTSV I/O (FromLTSV, ToLTSV),
      CSV I/O (FromCSV, ToCSV), and all 60 methods from LTSV::LINQ
    * Built-in JSON parser - No CPAN JSON module required
    * Pure Perl - No XS dependencies
    * Perl 5.005_03+ - Works on ancient and modern Perl

INCLUDED DOCUMENTATION
    The eg/ directory contains sample programs:

        eg/01_json_query.pl       FromJSON/Where/Select/OrderByDescending/Distinct/ToLookup
        eg/02_jsonl_query.pl      FromJSONL streaming, GroupBy, aggregation, ToJSONL
        eg/03_grouping.pl         GroupBy, ToLookup, GroupJoin, SelectMany, Join
        eg/04_sorting.pl          OrderBy/ThenBy multi-key sort, OrderByNum vs OrderByStr
        eg/05_json_ltsv_join.pl   JOIN main JSON x sub-table LTSV
        eg/06_ltsv_json_join.pl   JOIN main LTSV x sub-table JSON
        eg/07_csv_query.pl        FromCSV/Where/Select/GroupBy/OrderByNum/ToCSV
        eg/08_csv_json_join.pl    JOIN main CSV x sub-table JSON, CSV to JSON conversion

    The doc/ directory contains JSON::LINQ cheat sheets in 21 languages:

        doc/json_linq_cheatsheet.EN.txt   English

README  view on Meta::CPAN

    No C compiler required.  No non-core CPAN dependencies.

COMPATIBILITY
    Perl 5.005_03 and later.  Tested on Perl 5.005_03 through 5.42.
    Works on Windows and UNIX/Linux.  Pure Perl, no XS.

LIMITATIONS
    * Query objects can only be consumed once (iterator is exhausted
      after a terminal method).  Re-create the query to re-iterate.
    * FromJSON loads the entire file into memory.  Use FromJSONL for
      large files where streaming matters.
    * The built-in JSON parser does not support surrogate pairs
      (\uD800-\uDFFF) or circular reference detection in encoding.
    * ToLTSV sanitizes TAB/CR/LF in field values to single space to
      preserve the LTSV record/field structure.
    * ToCSV materialises the entire sequence before writing (to detect
      column names from the first record for the header row).
    * FromCSV reads one line at a time; CSV fields that span multiple
      lines (embedded newlines in quoted fields) are not supported.
    * The iterator protocol uses undef to signal end-of-sequence, so
      a JSON null cannot appear as a top-level element of a sequence.

doc/json_linq_cheatsheet.BM.txt  view on Meta::CPAN

 JSON::LINQ — Helaian Rujukan Pantas                        [BM] Bahasa Melayu
======================================================================

[ 1. 1. Mencipta Kueri ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # Dari fail CSV (baris pertama = pengepala, penstriman)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # tanpa pengepala
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

doc/json_linq_cheatsheet.EN.txt  view on Meta::CPAN

 JSON::LINQ Cheat Sheet                                    [EN] English
======================================================================

[ 1. Creating Queries ]

  use JSON::LINQ;

  # From a JSON file (top-level array)
  my $q = JSON::LINQ->FromJSON('data.json');

  # From a JSONL file (one JSON object per line, streaming)
  my $q = JSON::LINQ->FromJSONL('events.jsonl');

  # From a JSON string
  my $q = JSON::LINQ->FromJSONString('[{"id":1},{"id":2}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # From a CSV file (first row = header, streaming)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");        # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]); # headerless
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)],  # skip existing
                               skip_header=>1);

  # From an in-memory array
  my $q = JSON::LINQ->From(\@array);

  # Empty sequence

doc/json_linq_cheatsheet.FR.txt  view on Meta::CPAN

 JSON::LINQ Aide-mémoire                                       [FR] Français
======================================================================

[ 1. 1. Création de requêtes ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # Depuis un fichier CSV (1ère ligne = en-tête, streaming)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # sans en-tête
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

[ 2. 2. Filtrage ]

doc/json_linq_cheatsheet.ID.txt  view on Meta::CPAN

 JSON::LINQ Lembar Contekan                                    [ID] Bahasa Indonesia
======================================================================

[ 1. 1. Membuat Kueri ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # Dari file CSV (baris pertama = header, streaming)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # tanpa header
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

[ 2. 2. Penyaringan ]

doc/json_linq_cheatsheet.KO.txt  view on Meta::CPAN


[ 1. 쿼리 생성 ]

  use JSON::LINQ;
  # JSON 파일에서 읽기 (최상위 배열)
  my $q = JSON::LINQ->FromJSON('data.json');
  # JSONL 파일에서 읽기 (줄당 하나의 JSON 객체, 스트리밍)
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  # JSON 문자열에서
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');
  # FromLTSV: read an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # FromCSV: CSV 파일 읽기 (첫 행 = 헤더, 스트리밍)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # 헤더 없음
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  # 메모리 배열에서
  my $q = JSON::LINQ->From(\@array);
  # 빈 시퀀스
  my $q = JSON::LINQ->Empty();

doc/json_linq_cheatsheet.MY.txt  view on Meta::CPAN

 JSON::LINQ အမြန်ကိုးကားချက်                           [MY] မြန်မာဘာသာ
======================================================================

[ 1. မေးမြန်းမှု ဖန်တီးခြင်း ]

  use JSON::LINQ;

  # JSON ဖိုင်မှ (အထက်ဆုံး array)
  my $q = JSON::LINQ->FromJSON('data.json');

  # JSONL ဖိုင်မှ (streaming)
  my $q = JSON::LINQ->FromJSONL('events.jsonl');

  # JSON string မှ
  my $q = JSON::LINQ->FromJSONString('[{"id":1},{"id":2}]');

  # LTSV ဖိုင်မှ (label:value, TAB-ပိုင်းခြား, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');

  # CSV ဖိုင်မှ (ပထမအတန်း = ခေါင်းစဉ်၊ streaming)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");        # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]); # ခေါင်းစဉ်မပါ
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);

  # Memory ထဲ array မှ
  my $q = JSON::LINQ->From(\@array);

  # ဗလာ sequence
  my $q = JSON::LINQ->Empty();

doc/json_linq_cheatsheet.TL.txt  view on Meta::CPAN

 JSON::LINQ Cheat Sheet                                        [TL] Filipino
======================================================================

[ 1. 1. Paglikha ng Query ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # Mula sa CSV file (unang linya = header, streaming)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # walang header
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

[ 2. 2. Pagsasala ]

doc/json_linq_cheatsheet.TR.txt  view on Meta::CPAN

 JSON::LINQ Kopya Kağıdı                                       [TR] Türkçe
======================================================================

[ 1. 1. Sorgu OluÅŸturma ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # CSV dosyasından (ilk satır = başlık, akış)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # başlıksız
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

doc/json_linq_cheatsheet.TW.txt  view on Meta::CPAN


[ 1. 建立查詢 ]

  use JSON::LINQ;
  # 從JSON檔案讀取(頂層為陣列)
  my $q = JSON::LINQ->FromJSON('data.json');
  # 從JSONL檔案讀取(每行一個JSON物件,串流)
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  # 從JSON字串
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');
  # FromLTSV: read an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # 從 CSV 檔案讀取(首列為標題列,串流)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # 無標題列
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  # 從記憶體陣列
  my $q = JSON::LINQ->From(\@array);
  # 空序列
  my $q = JSON::LINQ->Empty();

doc/json_linq_cheatsheet.UZ.txt  view on Meta::CPAN

 JSON::LINQ Qo'llanma                                          [UZ] O'zbekcha
======================================================================

[ 1. 1. Sorov yaratish ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # CSV fayldan (birinchi qator = sarlavha, oqim)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # sarlavasiz
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

doc/json_linq_cheatsheet.VI.txt  view on Meta::CPAN

 JSON::LINQ Bảng Tóm Tắt                                      [VI] Tiếng Việt
======================================================================

[ 1. 1. Tạo truy vấn ]

  use JSON::LINQ;
  my $q = JSON::LINQ->FromJSON('data.json');
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  my $q = JSON::LINQ->FromJSONString('[{"id":1}]');

  # From an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # Từ file CSV (hàng đầu = tiêu đề, streaming)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # không có tiêu đề
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  my $q = JSON::LINQ->From(\@array);
  my $q = JSON::LINQ->Empty();
  my $q = JSON::LINQ->Range(1, 5);
  my $q = JSON::LINQ->Repeat('x', 3);

[ 2. 2. Lọc dữ liệu ]

doc/json_linq_cheatsheet.ZH.txt  view on Meta::CPAN


[ 1. 创建查询 ]

  use JSON::LINQ;
  # 从JSON文件读取(顶层为数组)
  my $q = JSON::LINQ->FromJSON('data.json');
  # 从JSONL文件读取(每行一个JSON对象,流式)
  my $q = JSON::LINQ->FromJSONL('events.jsonl');
  # 从JSON字符串
  my $q = JSON::LINQ->FromJSONString('[{"id":1},{"id":2}]');
  # FromLTSV: read an LTSV file (label:value, TAB-separated, streaming)
  my $q = JSON::LINQ->FromLTSV('data.ltsv');
  # 从 CSV 文件读取(第一行为标题行,流式)
  my $q = JSON::LINQ->FromCSV('data.csv');
  my $q = JSON::LINQ->FromCSV('data.csv', sep => "\t");         # TSV
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)]);  # 无标题行
  my $q = JSON::LINQ->FromCSV('f.csv', headers=>[qw(a b c)], skip_header=>1);
  # 从内存数组
  my $q = JSON::LINQ->From(\@array);
  # 空序列
  my $q = JSON::LINQ->Empty();

eg/02_jsonl_query.pl  view on Meta::CPAN

######################################################################
#
# 02_jsonl_query.pl - JSONL streaming query example
#
# Demonstrates:
#   - FromJSONL: read a JSONL file (streaming, one line at a time)
#   - Where: filter by field value
#   - Count: count matching records
#   - GroupBy: group by field
#   - Sum: aggregate field values
#   - ToJSONL: write results as JSONL
#
######################################################################

use strict;
BEGIN { if ($] < 5.006) { $INC{'warnings.pm'} = 'stub'; eval 'package warnings; sub import {}' } }

lib/JSON/LINQ.pm  view on Meta::CPAN

        print {*{$fhn}} _json_encode($record);
    });
    { no strict 'refs'; print {*{$fhn}} "\n]\n" }

    { no strict 'refs'; close($fhn) }
    return 1;
}

# ToJSONL - write sequence as a JSONL (JSON Lines) file
# Each element is encoded as one line of JSON.
# This is streaming-friendly and memory-efficient.
sub ToJSONL {
    my($self, $file) = @_;

    my $fhn = _open_fh('>', $file, 1);

    $self->ForEach(sub {
        my $record = shift;
        no strict 'refs';
        print {*{$fhn}} _json_encode($record), "\n";
    });

lib/JSON/LINQ.pm  view on Meta::CPAN


JSON::LINQ provides a LINQ-style query interface for JSON, JSONL
(JSON Lines), and LTSV (Labeled Tab-Separated Values) files. It is
the JSON counterpart of L<LTSV::LINQ>, sharing the same LINQ API and
adding JSON-specific I/O methods.

Key features:

=over 4

=item * B<Lazy evaluation> - O(1) memory for JSONL and LTSV streaming;
JSON arrays are loaded once then iterated lazily

=item * B<Method chaining> - Fluent, readable query composition

=item * B<DSL syntax> - Simple key-value filtering

=item * B<67 LINQ methods> - including JSON I/O (FromJSON, FromJSONL,
FromJSONString, ToJSON, ToJSONL), LTSV I/O (FromLTSV, ToLTSV),
CSV I/O (FromCSV, ToCSV), and all 60 methods from L<LTSV::LINQ>

lib/JSON/LINQ.pm  view on Meta::CPAN

=item * B<Empty()> - Empty sequence

=item * B<Repeat($element, $count)> - Repeated element

=back

=head2 What is JSONL?

JSONL (JSON Lines, also known as ndjson - newline-delimited JSON) is a
text format where each line is a valid JSON value (typically an object).
It is particularly suited for log files and streaming data because:

=over 4

=item * One record per line enables streaming with O(1) memory usage

=item * Compatible with standard Unix tools (grep, sed, awk)

=item * Easily appendable without rewriting the whole file

=item * Each line is independently parseable

=back

B<Format example:>

lib/JSON/LINQ.pm  view on Meta::CPAN


LINQ (Language Integrated Query) is the Microsoft .NET query API.
This module brings the same LINQ interface to JSON data in Perl.
See L<LTSV::LINQ> for a detailed description of the LINQ design philosophy.

=head1 INCLUDED DOCUMENTATION

The C<eg/> directory contains sample programs:

  eg/01_json_query.pl       FromJSON/Where/Select/OrderByDescending/Distinct/ToLookup
  eg/02_jsonl_query.pl      FromJSONL streaming, GroupBy, aggregation, ToJSONL
  eg/03_grouping.pl         GroupBy, ToLookup, GroupJoin, SelectMany, Join
  eg/04_sorting.pl          OrderBy/ThenBy multi-key sort, OrderByNum vs OrderByStr
  eg/05_json_ltsv_join.pl   JOIN main JSON x sub-table LTSV
  eg/06_ltsv_json_join.pl   JOIN main LTSV x sub-table JSON
  eg/07_csv_query.pl        FromCSV/Where/Select/GroupBy/OrderByNum/ToCSV
  eg/08_csv_json_join.pl    JOIN main CSV x sub-table JSON, CSV to JSON conversion

The C<doc/> directory contains JSON::LINQ cheat sheets in 21 languages:

  doc/json_linq_cheatsheet.EN.txt   English

lib/JSON/LINQ.pm  view on Meta::CPAN

as a one-element sequence.

B<File format:>

  [
    {"name": "Alice", "age": 30},
    {"name": "Bob",   "age": 25}
  ]

The entire file is read into memory and parsed once. For large files,
consider JSONL format with C<FromJSONL> for streaming access.

B<Concurrent use (e.g. Join/GroupJoin):> On Perl 5.006 and later,
each call to C<FromJSON> uses a distinct numbered filehandle slot, so
multiple iterators may be open simultaneously without interference.
On Perl 5.005_03, a unique numbered package glob is used per call
(JSON::LINQ::FH::H1, JSON::LINQ::FH::H2, ...) to achieve the same safety.

=item B<FromJSONL($filename)>

Read a JSONL (JSON Lines) file. Each non-empty line is parsed as a

lib/JSON/LINQ.pm  view on Meta::CPAN

  [
  {"age":30,"name":"Alice"},
  {"age":25,"name":"Bob"}
  ]

Hash keys are sorted alphabetically for deterministic output.

=item B<ToJSONL($filename)>

Write the sequence as a JSONL file. Each element is written as one line
of JSON. This is the streaming counterpart of C<ToJSON>.

  $query->ToJSONL("output.jsonl");

B<Output format:>

  {"age":30,"name":"Alice"}
  {"age":25,"name":"Bob"}

=back

lib/JSON/LINQ.pm  view on Meta::CPAN


JSON::LINQ and LTSV::LINQ are parallel modules sharing the same LINQ API.

  LTSV::LINQ  - LINQ for LTSV (Labeled Tab-Separated Values) files
  JSON::LINQ  - LINQ for JSON and JSONL files

Both share the same LINQ API. JSON::LINQ adds the following I/O methods
on top of LTSV::LINQ's interface:

  FromJSON($file)         - read JSON array file
  FromJSONL($file)        - read JSONL file (streaming)
  FromJSONString($json)   - read JSON string
  FromLTSV($file)         - read LTSV file (streaming)
  FromCSV($file)          - read CSV file (streaming, RFC 4180)
  ToJSON($file)           - write JSON array file
  ToJSONL($file)          - write JSONL file
  ToLTSV($file)           - write LTSV file (streaming)
  ToCSV($file)            - write CSV file

C<FromLTSV>, C<ToLTSV>, C<FromCSV>, and C<ToCSV> are provided so a
JSON::LINQ pipeline can JOIN against (or emit into) LTSV and CSV files
without requiring LTSV::LINQ or CSV::LINQ to be installed.

The internal iterator architecture is identical: each operator returns a
new query object wrapping a closure.

=head2 Memory Characteristics

  FromJSONL  - O(1) per record: one line at a time
  FromJSON   - O(n): entire file loaded once, then lazy iteration
  FromLTSV   - O(1) per record: one line at a time
  FromCSV    - O(1) per record: one line at a time
  ToJSON     - O(n): entire sequence collected for array output
  ToJSONL    - O(1) per record: streaming write
  ToLTSV     - O(1) per record: streaming write
  ToCSV      - O(n): entire sequence collected before writing header

=head1 COMPATIBILITY

=head2 Perl Version Support

Compatible with B<Perl 5.00503 and later>. See L<LTSV::LINQ> for the
full compatibility rationale (Universal Consensus 1998 / Perl 5.005_03).

=head2 Pure Perl Implementation



( run in 0.991 second using v1.01-cache-2.11-cpan-140bd7fdf52 )