Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pI6RJ-00084k-1t for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Jan 2023 11:17:09 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pI6RH-0007Yx-J0 for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Jan 2023 11:17:07 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pI6RH-0007Yo-5l for pgsql-hackers@lists.postgresql.org; Wed, 18 Jan 2023 11:17:07 +0000 Received: from out3-smtp.messagingengine.com ([66.111.4.27]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pI6RD-0006M1-HW for pgsql-hackers@lists.postgresql.org; Wed, 18 Jan 2023 11:17:06 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id EFC0F5C00DD; Wed, 18 Jan 2023 06:17:01 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Wed, 18 Jan 2023 06:17:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1674040621; x=1674127021; bh=V CVUfVFladGgD/h0ZkeMGwEYhmYIUQVEDAUGo3sq7AU=; b=nTv8Ev56jmFHBvJ4M cs1M3ILAPBlK0rh9sTNQfyvBocdRleWe8Jmtf6tXLXqFmk01X6kZD0U4wb7TJG3N 2OYaGZbSvUYg1HWmEbFqF2US6T56Y568zdwC+meYoq7Y+6ArzoWodxtUz7uNFB90 wAgj5oNFhkflBT4p0bGp6MMbggJ3tfJzyNByWSpIM52i8OueXND80MlHmdaa9m9h L4cozHro83FlodK7/Y8pa1LioiNFb7L/RqU5hc4ueU6eUnuaNg3AnkOrgIaYShkR IrSdY2uc6fNpQdf4KnNUcOnalWqpufPhSj9XvnXrHBs8VU7d5mWmlGLp4aTOPSsN NsExQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedruddtkedgvdeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfggtggugfgjsehtke ertddttdejnecuhfhrohhmpeetlhhvrghrohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhr vgesrghlvhhhrdhnohdqihhprdhorhhgqeenucggtffrrghtthgvrhhnpedvudeftdfgve dvgfffgefhveduvdeghfdugedufffhgeduudettedthfdvgeffheenucffohhmrghinhep vghnthgvrhhprhhishgvuggsrdgtohhmpdhtfihithhtvghrrdgtohhmnecuvehluhhsth gvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghlvhhhvghrrhgvsegr lhhvhhdrnhhoqdhiphdrohhrgh X-ME-Proxy: Feedback-ID: ia2694551:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 18 Jan 2023 06:17:01 -0500 (EST) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id D9AB398; Wed, 18 Jan 2023 12:09:42 +0100 (CET) Date: Wed, 18 Jan 2023 12:09:42 +0100 From: Alvaro Herrera To: Tom Lane Cc: pgsql-hackers@lists.postgresql.org, sebastian.patino-lang@posteo.net Subject: Re: Rethinking the implementation of ts_headline() Message-ID: <20230118110942.od2naagwp6molgxz@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <840.1669405935@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk I tried this other test, based on looking at the new regression tests you added, SELECT ts_headline('english', ' Day after day, day after day, We stuck, nor breath nor motion, As idle as a painted Ship Upon a painted Ocean. Water, water, every where And all the boards did shrink; Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) ', to_tsquery('english', '(day & drink) | (idle & painted)'), 'MaxFragments=5, MaxWords=9, MinWords=4'); ts_headline ───────────────────────────────────────── motion, ↵ As idle as a painted Ship↵ Upon (1 fila) and was surprised that the match for the 'day & drink' arm of the OR disappears from the reported headline. This is what 15 reports for the same query: SELECT ts_headline('english', ' Day after day, day after day, We stuck, nor breath nor motion, As idle as a painted Ship Upon a painted Ocean. Water, water, every where And all the boards did shrink; Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) ', to_tsquery('english', '(day & drink) | (idle & painted)'), 'MaxFragments=5, MaxWords=9, MinWords=4'); ts_headline ─────────────────────────────────────────────────────────── Day after day, day after day,↵ We stuck ... motion, ↵ As idle as a painted Ship ↵ Upon (1 fila) I think this was better. 15 seems to fail in other ways; for instance, 'drink' is not highlighted in the headline when the OR matches, but if the other arm of the OR doesn't match, it is; for example both 15 and master return the same for this one: SELECT ts_headline('english', ' Day after day, day after day, We stuck, nor breath nor motion, As idle as a painted Ship Upon a painted Ocean. Water, water, every where And all the boards did shrink; Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) ', to_tsquery('english', '(day & drink) | (mountain & backpack)'), 'MaxFragments=5, MaxWords=9, MinWords=4'); ts_headline ─────────────────────────────────────────────────────────── Day after day, day after day,↵ We stuck ... drop to drink. ↵ S. T. Coleridge (1 fila) Another thing I think might be a regression is the way fragments are selected. Consider what happens if I change the "idle & painted" in the earlier query to "idle <-> painted", and MaxWords is kept low: SELECT ts_headline('english', ' Day after day, day after day, We stuck, nor breath nor motion, As idle as a painted Ship Upon a painted Ocean. Water, water, every where And all the boards did shrink; Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) ', to_tsquery('english', '(day & drink) | (idle <-> painted)'), 'MaxFragments=5, MaxWords=9, MinWords=4'); ts_headline ─────────────────────────────────────────────── day, ↵ We stuck, nor breath nor motion, ↵ As idle ... painted Ship ↵ Upon a painted Ocean. ↵ Water, water, every ... drop to drink.↵ S. T. Coleridge (1 fila) Note that it chose to put a fragment delimiter exactly in the middle of the phrase match, where the stop words are. If I raise MaxWords, it is of course much better, I suppose because the word limit doesn't force a new fragment, SELECT ts_headline('english', ' Day after day, day after day, We stuck, nor breath nor motion, As idle as a painted Ship Upon a painted Ocean. Water, water, every where And all the boards did shrink; Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) ', to_tsquery('english', '(day & drink) | (idle <-> painted)'), 'MaxFragments=5, MaxWords=25, MinWords=4'); ts_headline ────────────────────────────────────────────────── after day, day after day, ↵ We stuck, nor breath nor motion, ↵ As idle as a painted Ship ↵ Upon a painted Ocean. ↵ Water, water, every where ... boards did shrink;↵ Water, water, every where, ↵ Nor any drop to drink. ↵ S. T. Coleridge (1 fila) But in 15, the query with low MaxWords does this instead, where the fragment delimiter occurs just *before* the phrasal match. SELECT ts_headline('english', ' Day after day, day after day, We stuck, nor breath nor motion, As idle as a painted Ship Upon a painted Ocean. Water, water, every where And all the boards did shrink; Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) ', to_tsquery('english', '(day & drink) | (idle <-> painted)'), 'MaxFragments=5, MaxWords=9, MinWords=4'); ts_headline ─────────────────────────────────────────────────────────── Day after day, day after day,↵ We stuck ... idle as a painted Ship ↵ Upon a painted Ocean ... drop to drink. ↵ S. T. Coleridge (1 fila) (Both 15 and master highlight 'painted' in the "Upon a painted Ocean" verse, which perhaps they shouldn't do, since it's not preceded by 'idle'.) (I think it's super annoying that the fragment separation algorithm fails to preserve newlines between verses as it adds the '...' separator. But I guess poetry is not the main use case for text search anyway, so it probably doesn't matter much.) -- Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/ "Every machine is a smoke machine if you operate it wrong enough." https://twitter.com/libseybieda/status/1541673325781196801