• 做 spreadsheet ,我觉得最难的一点在于解析表达式 (对于没有编译原理基础的人来说),如何避免因为循环依赖导致的栈溢出。比如说 A1 的值是 =A1+A2 ,A2 的值是 =A1+A2。这个库也没解决这个问题:

    不知道有没有简单的思路,或者轻便的第三方库来解决这个问题。

  • @hooopo 好的,谢谢了,我也看到了你发到一篇关于 PostgreSQL 全文搜索的贴子 (https://ruby-china.org/topics/38153),我再研究一下。

  • @hooopo 谢谢! 以下是 explain: (实际项目中表是 episodes)

    • 记录总数: 774825
    [1] pry(main)> Episode.count
       (307.6ms)  SELECT COUNT(*) FROM "episodes"
    => 774825
    
    • seach_by_title
    [1] pry(main)> Episode.search_by_title('adventure').explain
      Episode Load (85.9ms)  SELECT "episodes".* FROM "episodes" INNER JOIN (SELECT "episodes"."id" AS pg_search_id, (ts_rank(("episodes"."tsv_title"), (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*')), 2)) AS rank FROM "episodes" WHERE ((("episodes"."tsv_title") @@ (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*'))))) AS pg_search_a8ace1a76c218f36a59a58 ON "episodes"."id" = pg_search_a8ace1a76c218f36a59a58.pg_search_id ORDER BY pg_search_a8ace1a76c218f36a59a58.rank DESC, "episodes"."id" ASC
    => EXPLAIN for: SELECT "episodes".* FROM "episodes" INNER JOIN (SELECT "episodes"."id" AS pg_search_id, (ts_rank(("episodes"."tsv_title"), (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*')), 2)) AS rank FROM "episodes" WHERE ((("episodes"."tsv_title") @@ (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*'))))) AS pg_search_a8ace1a76c218f36a59a58 ON "episodes"."id" = pg_search_a8ace1a76c218f36a59a58.pg_search_id ORDER BY pg_search_a8ace1a76c218f36a59a58.rank DESC, "episodes"."id" ASC
                                                   QUERY PLAN
    ---------------------------------------------------------------------------------------------------------
     Sort  (cost=4050.16..4051.01 rows=341 width=1513)
       Sort Key: (ts_rank(episodes_1.tsv_title, '''adventure'':*'::tsquery, 2)) DESC, episodes.id
       ->  Nested Loop  (cost=34.96..4035.81 rows=341 width=1513)
             ->  Bitmap Heap Scan on episodes episodes_1  (cost=34.54..1306.26 rows=327 width=103)
                   Recheck Cond: (tsv_title @@ '''adventure'':*'::tsquery)
                   ->  Bitmap Index Scan on index_episodes_on_tsv_title  (cost=0.00..34.45 rows=327 width=0)
                         Index Cond: (tsv_title @@ '''adventure'':*'::tsquery)
             ->  Index Scan using episodes_pkey on episodes  (cost=0.42..8.34 rows=1 width=1509)
                   Index Cond: (id = episodes_1.id)
    (9 rows)
    
    • search_by_desc
    [2] pry(main)> Episode.search_by_desc('adventure').explain
      Episode Load (2663.1ms)  SELECT "episodes".* FROM "episodes" INNER JOIN (SELECT "episodes"."id" AS pg_search_id, (ts_rank(("episodes"."tsv_description"), (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*')), 2)) AS rank FROM "episodes" WHERE ((("episodes"."tsv_description") @@ (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*'))))) AS pg_search_a8ace1a76c218f36a59a58 ON "episodes"."id" = pg_search_a8ace1a76c218f36a59a58.pg_search_id ORDER BY pg_search_a8ace1a76c218f36a59a58.rank DESC, "episodes"."id" ASC
    => EXPLAIN for: SELECT "episodes".* FROM "episodes" INNER JOIN (SELECT "episodes"."id" AS pg_search_id, (ts_rank(("episodes"."tsv_description"), (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*')), 2)) AS rank FROM "episodes" WHERE ((("episodes"."tsv_description") @@ (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*'))))) AS pg_search_a8ace1a76c218f36a59a58 ON "episodes"."id" = pg_search_a8ace1a76c218f36a59a58.pg_search_id ORDER BY pg_search_a8ace1a76c218f36a59a58.rank DESC, "episodes"."id" ASC
                                                          QUERY PLAN
    ----------------------------------------------------------------------------------------------------------------------
     Gather Merge  (cost=24792.34..24997.50 rows=1784 width=1513)
       Workers Planned: 1
       ->  Sort  (cost=23792.33..23796.79 rows=1784 width=1513)
             Sort Key: (ts_rank(episodes_1.tsv_description, '''adventure'':*'::tsquery, 2)) DESC, episodes.id
             ->  Nested Loop  (cost=78.94..23695.99 rows=1784 width=1513)
                   ->  Parallel Bitmap Heap Scan on episodes episodes_1  (cost=78.51..10578.73 rows=1709 width=201)
                         Recheck Cond: (tsv_description @@ '''adventure'':*'::tsquery)
                         ->  Bitmap Index Scan on index_episodes_on_tsv_description  (cost=0.00..77.79 rows=2905 width=0)
                               Index Cond: (tsv_description @@ '''adventure'':*'::tsquery)
                   ->  Index Scan using episodes_pkey on episodes  (cost=0.42..7.67 rows=1 width=1509)
                         Index Cond: (id = episodes_1.id)
    (11 rows)
    
    • search_by_title_desc
    [3] pry(main)> Episode.search_by_title_desc('adventure').explain
      Episode Load (10290.7ms)  SELECT "episodes".* FROM "episodes" INNER JOIN (SELECT "episodes"."id" AS pg_search_id, (ts_rank(("episodes"."tsv_title" || "episodes"."tsv_description"), (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*')), 2)) AS rank FROM "episodes" WHERE ((("episodes"."tsv_title" || "episodes"."tsv_description") @@ (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*'))))) AS pg_search_a8ace1a76c218f36a59a58 ON "episodes"."id" = pg_search_a8ace1a76c218f36a59a58.pg_search_id ORDER BY pg_search_a8ace1a76c218f36a59a58.rank DESC, "episodes"."id" ASC
    => EXPLAIN for: SELECT "episodes".* FROM "episodes" INNER JOIN (SELECT "episodes"."id" AS pg_search_id, (ts_rank(("episodes"."tsv_title" || "episodes"."tsv_description"), (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*')), 2)) AS rank FROM "episodes" WHERE ((("episodes"."tsv_title" || "episodes"."tsv_description") @@ (to_tsquery('simple', ''' ' || 'adventure' || ' ''' || ':*'))))) AS pg_search_a8ace1a76c218f36a59a58 ON "episodes"."id" = pg_search_a8ace1a76c218f36a59a58.pg_search_id ORDER BY pg_search_a8ace1a76c218f36a59a58.rank DESC, "episodes"."id" ASC
                                                                 QUERY PLAN
    ------------------------------------------------------------------------------------------------------------------------------------
     Gather Merge  (cost=242738.45..244331.76 rows=13656 width=1513)
       Workers Planned: 2
       ->  Sort  (cost=241738.43..241755.50 rows=6828 width=1513)
             Sort Key: (ts_rank((episodes_1.tsv_title || episodes_1.tsv_description), '''adventure'':*'::tsquery, 2)) DESC, episodes.id
             ->  Nested Loop  (cost=0.42..236799.08 rows=6828 width=1513)
                   ->  Parallel Seq Scan on episodes episodes_1  (cost=0.00..198085.56 rows=6542 width=300)
                         Filter: ((tsv_title || tsv_description) @@ '''adventure'':*'::tsquery)
                   ->  Index Scan using episodes_pkey on episodes  (cost=0.42..5.91 rows=1 width=1509)
                         Index Cond: (id = episodes_1.id)
    (9 rows)
    
  • gatsby 开一个博客很容易 at 2019年01月25日

    之前不了解 GraphQL 的看这部分可能费点劲,如果之前了解过这部分都可以跳过了。

  • 涨知识了

  • 的确奇芭:

    [23] pry(main)> Date.parse("heh")
    ArgumentError: invalid date
    from (pry):23:in `parse'
    
    [25] pry(main)> Date.parse(" fc03bb56-6c12-48fb-b47e-4c266fe57c43")
    => Thu, 03 Jan 2019
    
    [28] pry(main)> Date.parse("fc03bb56-6c12-48fb-b47e-4c266fe57c45")
    => Thu, 03 Jan 2019
    [29] pry(main)> Date.parse("ac03bb56-6c12-48fb-b47e-4c266fe57c45")
    => Thu, 03 Jan 2019
    
    [30] pry(main)> Date.parse("a-b-c-d-e")
    ArgumentError: invalid date
    from (pry):29:in `parse'
    
    [33] pry(main)> Date.parse("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")
    ArgumentError: invalid date
    from (pry):32:in `parse'
    
  • 没看懂,这是什么用法?

  • gatsby 开一个博客很容易 at 2019年01月18日

    前段时间也迁移了一把,从 Jekyll 迁移到了 Gatsby,相比 Jekyll,Gatsby 更灵活,自己可以控制更多细节。https://baurine.netlify.com/2018/12/08/migrate-to-gatsby/

  • 第二批到的。

  • 通篇看下来不是很 breaking 啊,感觉改变的多是内部的实现,最上层的 config 的写法好像没什么变化。