Quick Start

What you need

CQLi implements the Chess Query Language (CQL) to search chess game databases stored in PGN format. Below are several simple examples to provide an idea of what it looks like to use CQLi. See the Examples section for additional examples with more in-depth commentary. The Reference Manual (manual.pdf) distributed with CQLi includes even more examples and comprehensive details about every aspect of the product.

Most of the queries below contain a count representing the number of matching games from a selection of one million games from lichess.org along with links to 10 sample matches.

Brief Introduction

A CQL query consists of a series of filters. CQLi evaluates the query against every position in every game of the provided PGN file. Matching positions are those for which all filters in the query are true. Games with matching positions are written to the output file.

The -i option is used to specify the input PGN file and the -o option is used to specify the output file. The -cql option may be used to provided the query. Queries can also be provided in a text file with a .cql extension that is then referenced on the command line in place of the -cql option.

By default, matching positions are commented with the string "CQL", this may be changed or suppressed using the -matchstring option. The -silent option will prevent CQLi from adding any comments. By default, CQLi will store all matching games in memory before writing them out. If the query matches a large number of games, this could result in memory exhuastion so the -nosort option can be used to write games out as they are found.

In the examples below, replace input.pgn with your input PGN file, output.pgn with the desired output file, and cqli with the name of the appropriate binary (e.g. cqli.exe for Windows).

If you are testing out the below queries with huge PGN database files (millions of games), you can use the -g option to limit processing to games in a certain range if you do not want to wait while CQLi processes the entire file. For example the option -g 1 100000 will limit processing to the first 100,000 games.

Short Examples

Remove all comments from a PGN file

cqli -i input.pgn -o output.pgn -silent -nosort -cql 'removecomment'

Find decisive games with over 100 moves

cqli -i input.pgn -o output.pgn -cql 'terminal result "1-0" or result "0-1" movenumber > 100'
356 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Failed conversion of KBBvK ending

cqli -i input.pgn -o output.pgn -cql 'terminal result "1/2-1/2" flipcolor { A == K a == [kb] == 3 }'
17 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Mate in KNBvK ending

cqli -i input.pgn -o output.pgn -cql 'terminal mate flipcolor { A == K a == [knb] == 3}'
16 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Win by player 400+ Elo lower

cqli -i input.pgn -o output.pgn -cql 'initial flipcolor { result "1-0" elo white + 400 <= elo black }'
2376 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Castling opposite sides

cqli -i input.pgn -o output.pgn -cql 'initial find move o-o find move o-o-o'
148034 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Bishop pins rook to queen

cqli -i input.pgn -o output.pgn -cql 'flipcolor pin from B through r to q'
6736 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Positions that match a specific Zobrist key

cqli -i input.pgn -o output.pgn -cql 'zobristkey == "9f2e3a461655ff6b"'
51 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Populate a tag named EndFEN with the FEN of the ending position

cqli -i input.pgn -o output.pgn -silent -nosort -cql 'terminal settag("EndFEN" currentfen)'

Promotion(s) by both sides

cqli -i input.pgn -o output.pgn -cql 'initial find { wtm move promote A } find { btm move promote A }'
11539 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Both side have promoted queens on the board

cqli -i input.pgn -o output.pgn -cql 'promotedpieces & Q promotedpieces & q'
7362 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

2+ consecutive promotions

cqli -i input.pgn -o output.pgn -cql 'line --> move promote A {2,}'
4307 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

Underpromotions

cqli -i input.pgn -o output.pgn -cql 'move promote [BNR]'
3115 games out of 1,000,000 (Sample matches: #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 )

For more complex queries with in-depth commentary, see the full Examples page →