]> git.openstreetmap.org Git - nominatim.git/blob - src/nominatim_db/clicmd/index.py
c0619f34db410e7ffc618a06dea12130782ff684
[nominatim.git] / src / nominatim_db / clicmd / index.py
1 # SPDX-License-Identifier: GPL-3.0-or-later
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2024 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Implementation of the 'index' subcommand.
9 """
10 import argparse
11 import asyncio
12
13 import psutil
14
15 from ..db import status
16 from ..db.connection import connect
17 from .args import NominatimArgs
18
19 # Do not repeat documentation of subcommand classes.
20 # pylint: disable=C0111
21 # Using non-top-level imports to avoid eventually unused imports.
22 # pylint: disable=E0012,C0415
23
24
25 class UpdateIndex:
26     """\
27     Reindex all new and modified data.
28
29     Indexing is the process of computing the address and search terms for
30     the places in the database. Every time data is added or changed, indexing
31     needs to be run. Imports and replication updates automatically take care
32     of indexing. For other cases, this function allows to run indexing manually.
33     """
34
35     def add_args(self, parser: argparse.ArgumentParser) -> None:
36         group = parser.add_argument_group('Filter arguments')
37         group.add_argument('--boundaries-only', action='store_true',
38                            help="""Index only administrative boundaries.""")
39         group.add_argument('--no-boundaries', action='store_true',
40                            help="""Index everything except administrative boundaries.""")
41         group.add_argument('--minrank', '-r', type=int, metavar='RANK', default=0,
42                            help='Minimum/starting rank')
43         group.add_argument('--maxrank', '-R', type=int, metavar='RANK', default=30,
44                            help='Maximum/finishing rank')
45
46
47     def run(self, args: NominatimArgs) -> int:
48         asyncio.run(self._do_index(args))
49
50         if not args.no_boundaries and not args.boundaries_only \
51            and args.minrank == 0 and args.maxrank == 30:
52             with connect(args.config.get_libpq_dsn()) as conn:
53                 status.set_indexed(conn, True)
54
55         return 0
56
57
58     async def _do_index(self, args: NominatimArgs) -> None:
59         from ..tokenizer import factory as tokenizer_factory
60
61         tokenizer = tokenizer_factory.get_tokenizer_for_db(args.config)
62         from ..indexer.indexer import Indexer
63
64         indexer = Indexer(args.config.get_libpq_dsn(), tokenizer,
65                           args.threads or psutil.cpu_count() or 1)
66
67         has_pending = True # run at least once
68         while has_pending:
69             if not args.no_boundaries:
70                 await indexer.index_boundaries(args.minrank, args.maxrank)
71             if not args.boundaries_only:
72                 await indexer.index_by_rank(args.minrank, args.maxrank)
73                 await indexer.index_postcodes()
74             has_pending = indexer.has_pending()