Skip to content

Commit 0a1302d

Browse files
jenkins-botGerrit Code Review
authored andcommitted
Merge "Search: Enable search by ID in SqlTermStoreSearchEngine"
2 parents 05e2124 + 1095250 commit 0a1302d

File tree

4 files changed

+314
-26
lines changed

4 files changed

+314
-26
lines changed

repo/domains/search/src/Domain/Model/MatchedData.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
class MatchedData {
99

1010
private string $type;
11-
private string $languageCode;
11+
private ?string $languageCode;
1212
private string $text;
1313

14-
public function __construct( string $type, string $languageCode, string $text ) {
14+
public function __construct( string $type, ?string $languageCode, string $text ) {
1515
$this->type = $type;
1616
$this->languageCode = $languageCode;
1717
$this->text = $text;
@@ -21,7 +21,7 @@ public function getType(): string {
2121
return $this->type;
2222
}
2323

24-
public function getLanguageCode(): string {
24+
public function getLanguageCode(): ?string {
2525
return $this->languageCode;
2626
}
2727

repo/domains/search/src/Infrastructure/DataAccess/SqlTermStoreSearchEngine.php

Lines changed: 109 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
namespace Wikibase\Repo\Domains\Search\Infrastructure\DataAccess;
44

5+
use Wikibase\DataModel\Entity\BasicEntityIdParser;
6+
use Wikibase\DataModel\Entity\EntityIdParsingException;
57
use Wikibase\DataModel\Entity\Item;
8+
use Wikibase\DataModel\Entity\ItemId;
69
use Wikibase\DataModel\Entity\Property;
10+
use Wikibase\DataModel\Entity\PropertyId;
11+
use Wikibase\DataModel\Services\Lookup\EntityLookup;
712
use Wikibase\DataModel\Term\TermTypes;
813
use Wikibase\Lib\LanguageFallbackChainFactory;
914
use Wikibase\Lib\Store\MatchingTermsLookup;
1015
use Wikibase\Lib\TermIndexEntry;
16+
use Wikibase\Repo\Domains\Search\Domain\Model\Description;
1117
use Wikibase\Repo\Domains\Search\Domain\Model\ItemSearchResult;
1218
use Wikibase\Repo\Domains\Search\Domain\Model\ItemSearchResults;
1319
use Wikibase\Repo\Domains\Search\Domain\Model\Label;
@@ -26,15 +32,18 @@
2632
class SqlTermStoreSearchEngine implements ItemSearchEngine, PropertySearchEngine {
2733

2834
private MatchingTermsLookup $matchingTermsLookup;
35+
private EntityLookup $entityLookup;
2936
private TermRetriever $termRetriever;
3037
private LanguageFallbackChainFactory $languageFallbackChainFactory;
3138

3239
public function __construct(
3340
MatchingTermsLookup $matchingTermsLookup,
41+
EntityLookup $entityLookup,
3442
TermRetriever $termRetriever,
3543
LanguageFallbackChainFactory $languageFallbackChainFactory
3644
) {
3745
$this->matchingTermsLookup = $matchingTermsLookup;
46+
$this->entityLookup = $entityLookup;
3847
$this->termRetriever = $termRetriever;
3948
$this->languageFallbackChainFactory = $languageFallbackChainFactory;
4049
}
@@ -45,10 +54,26 @@ public function searchItemByLabel(
4554
int $limit,
4655
int $offset
4756
): ItemSearchResults {
48-
return new ItemSearchResults( ...array_map(
49-
$this->convertResult( ItemSearchResult::class, $languageCode ),
50-
$this->findMatchingLabelsAndAliases( Item::ENTITY_TYPE, $searchTerm, $languageCode, $limit, $offset )
51-
) );
57+
$results = [];
58+
$resultById = $this->searchItemById( $searchTerm, $languageCode );
59+
if ( $resultById ) {
60+
// when an Item was found by ID
61+
if ( $offset === 0 ) {
62+
// add it on top of the first page and reduce limit by one
63+
$results[] = $resultById;
64+
$limit--;
65+
} else {
66+
// reduce offset by one on consecutive pages
67+
$offset--;
68+
}
69+
}
70+
return new ItemSearchResults(
71+
...$results,
72+
...array_map(
73+
$this->convertResult( ItemSearchResult::class, $languageCode ),
74+
$this->findMatchingLabelsAndAliases( Item::ENTITY_TYPE, $searchTerm, $languageCode, $limit, $offset )
75+
)
76+
);
5277
}
5378

5479
public function searchPropertyByLabel(
@@ -57,10 +82,26 @@ public function searchPropertyByLabel(
5782
int $limit,
5883
int $offset
5984
): PropertySearchResults {
60-
return new PropertySearchResults( ...array_map(
61-
$this->convertResult( PropertySearchResult::class, $languageCode ),
62-
$this->findMatchingLabelsAndAliases( Property::ENTITY_TYPE, $searchTerm, $languageCode, $limit, $offset )
63-
) );
85+
$results = [];
86+
$resultById = $this->searchPropertyById( $searchTerm, $languageCode );
87+
if ( $resultById ) {
88+
// when a Property was found by ID
89+
if ( $offset === 0 ) {
90+
// add it on top of the first page and reduce limit by one
91+
$results[] = $resultById;
92+
$limit--;
93+
} else {
94+
// reduce offset by one on consecutive pages
95+
$offset--;
96+
}
97+
}
98+
return new PropertySearchResults(
99+
...$results,
100+
...array_map(
101+
$this->convertResult( PropertySearchResult::class, $languageCode ),
102+
$this->findMatchingLabelsAndAliases( Property::ENTITY_TYPE, $searchTerm, $languageCode, $limit, $offset )
103+
)
104+
);
64105
}
65106

66107
/**
@@ -98,4 +139,64 @@ private function convertResult( string $resultClass, string $languageCode ): cal
98139
};
99140
}
100141

142+
private function searchItemById( string $searchTerm, string $languageCode ): ?ItemSearchResult {
143+
$item = $this->lookupItemById( $searchTerm );
144+
if ( !$item ) {
145+
return null;
146+
}
147+
148+
$fallbackChain = $this->languageFallbackChainFactory->newFromLanguageCode( $languageCode );
149+
$itemLabel = $fallbackChain->extractPreferredValue( $item->getLabels()->toTextArray() );
150+
$itemDescription = $fallbackChain->extractPreferredValue( $item->getDescriptions()->toTextArray() );
151+
return new ItemSearchResult(
152+
$item->getId(),
153+
$itemLabel ? new Label( $itemLabel['language'], $itemLabel['value'] ) : null,
154+
$itemDescription ? new Description( $itemDescription['language'], $itemDescription['value'] ) : null,
155+
new MatchedData( 'entityId', null, $item->getId()->getSerialization() )
156+
);
157+
}
158+
159+
private function searchPropertyById( string $searchTerm, string $languageCode ): ?PropertySearchResult {
160+
$property = $this->lookupPropertyById( $searchTerm );
161+
if ( !$property ) {
162+
return null;
163+
}
164+
165+
$fallbackChain = $this->languageFallbackChainFactory->newFromLanguageCode( $languageCode );
166+
$propertyLabel = $fallbackChain->extractPreferredValue( $property->getLabels()->toTextArray() );
167+
$propertyDescription = $fallbackChain->extractPreferredValue( $property->getDescriptions()->toTextArray() );
168+
return new PropertySearchResult(
169+
$property->getId(),
170+
$propertyLabel ? new Label( $propertyLabel['language'], $propertyLabel['value'] ) : null,
171+
$propertyDescription ? new Description( $propertyDescription['language'], $propertyDescription['value'] ) : null,
172+
new MatchedData( 'entityId', null, $property->getId()->getSerialization() )
173+
);
174+
}
175+
176+
private function lookupItemById( string $searchTerm ): ?Item {
177+
try {
178+
$entityId = ( new BasicEntityIdParser() )->parse( $searchTerm );
179+
} catch ( EntityIdParsingException $ex ) {
180+
$entityId = null;
181+
}
182+
183+
$item = $entityId instanceof ItemId ? $this->entityLookup->getEntity( $entityId ) : null;
184+
'@phan-var \Wikibase\DataModel\Entity\Item $item';
185+
186+
return $item instanceof Item ? $item : null;
187+
}
188+
189+
private function lookupPropertyById( string $searchTerm ): ?Property {
190+
try {
191+
$entityId = ( new BasicEntityIdParser() )->parse( $searchTerm );
192+
} catch ( EntityIdParsingException $ex ) {
193+
$entityId = null;
194+
}
195+
196+
$property = $entityId instanceof PropertyId ? $this->entityLookup->getEntity( $entityId ) : null;
197+
'@phan-var \Wikibase\DataModel\Entity\Property $property';
198+
199+
return $property instanceof Property ? $property : null;
200+
}
201+
101202
}

repo/domains/search/src/WbSearch.ServiceWiring.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
: new SqlTermStoreSearchEngine(
7474
WikibaseRepo::getMatchingTermsLookupFactory( $services )
7575
->getLookupForSource( WikibaseRepo::getLocalEntitySource( $services ) ),
76+
WikibaseRepo::getEntityLookup( $services ),
7677
new TermRetriever( WikibaseRepo::getFallbackLabelDescriptionLookupFactory( $services ), $services->getLanguageFactory() ),
7778
WikibaseRepo::getLanguageFallbackChainFactory( $services )
7879
);

0 commit comments

Comments
 (0)