OPS-408: fix searchShopText (#52)

* OPS-408: fix searchShopText

* fix setUp()
This commit is contained in:
Fedor Shimich 2024-03-18 12:44:39 +03:00 committed by GitHub
parent 8c6b7299e1
commit 03fffdd027
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 641 additions and 384 deletions

View File

@ -1,6 +1,7 @@
package dev.vality.deanonimus.converter; package dev.vality.deanonimus.converter;
import dev.vality.damsel.deanonimus.SearchShopHit; import dev.vality.damsel.deanonimus.SearchShopHit;
import dev.vality.damsel.deanonimus.Shop;
import dev.vality.deanonimus.domain.Party; import dev.vality.deanonimus.domain.Party;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.opensearch.client.opensearch.core.SearchResponse; import org.opensearch.client.opensearch.core.SearchResponse;
@ -8,6 +9,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;
@ -21,14 +23,40 @@ public class SearchHitShopConverter {
public List<SearchShopHit> convert(SearchResponse<Party> searchHits, String text) { public List<SearchShopHit> convert(SearchResponse<Party> searchHits, String text) {
var hits = new ArrayList<SearchShopHit>(); var hits = new ArrayList<SearchShopHit>();
for (var searchHit : searchHits.hits().hits()) { for (var searchHit : searchHits.hits().hits()) {
hits.addAll(shopListConverter.convert(searchHit.source().getShops()).values() var shops = searchHit.source().getShops();
.stream() if (isContainCommonFields(searchHit.source(), text)) {
.filter(shop -> containsIgnoreCase(shop.getId(), text) hits.addAll(shopListConverter.convert(shops).values()
|| containsIgnoreCase(shop.getLocation().getUrl(), text) .stream()
|| containsIgnoreCase(shop.getDetails().getName(), text)) .map(shop ->
.map(shop -> new SearchShopHit(searchHit.score(), shop, partyConverter.convert(searchHit.source()))) new SearchShopHit(searchHit.score(), shop, partyConverter.convert(searchHit.source())))
.toList()); .toList());
} else {
hits.addAll(shopListConverter.convert(shops).values()
.stream()
.filter(shop -> filterByShopFields(shop, text))
.map(shop ->
new SearchShopHit(searchHit.score(), shop, partyConverter.convert(searchHit.source())))
.toList());
}
} }
return hits; return hits;
} }
private boolean filterByShopFields(Shop shop, String text) {
return containsIgnoreCase(shop.getId(), text)
|| containsIgnoreCase(shop.getLocation().getUrl(), text)
|| containsIgnoreCase(shop.getDetails().getName(), text)
|| containsIgnoreCase(shop.getDetails().getDescription(), text)
|| containsIgnoreCase(shop.getContractId(), text);
}
private boolean isContainCommonFields(Party party, String text) {
var contracts = Optional.ofNullable(party.getContracts());
var contractors = Optional.ofNullable(party.getContractors());
return containsIgnoreCase(party.getId(), text)
|| containsIgnoreCase(party.getEmail(), text)
|| contracts.map(list -> list.stream().anyMatch(e -> containsIgnoreCase(e.getId(), text))).orElse(false)
|| contractors.map(list ->
list.stream().anyMatch(e -> containsIgnoreCase(e.getId(), text))).orElse(false);
}
} }

View File

@ -0,0 +1,82 @@
package dev.vality.deanonimus.db;
import dev.vality.deanonimus.domain.Party;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.opensearch._types.query_dsl.*;
import org.opensearch.client.opensearch.core.SearchResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class SearchByShopDao implements SearchDao {
@Value("${data.response.limit}")
private Integer responseLimit;
private final OpenSearchClient openSearchClient;
@Override
public SearchResponse<Party> searchParty(String text) {
var queryBuilder = new BoolQuery.Builder()
.should(searchBestFields(text, keywords()),
searchPhrasePrefix(text, fields()))
.build();
return search(queryBuilder);
}
@SneakyThrows
private SearchResponse<Party> search(BoolQuery queryBuilder) {
return openSearchClient.search(
s -> s
.size(responseLimit)
.query(new Query.Builder()
.bool(queryBuilder)
.build()),
Party.class);
}
private List<String> keywords() {
return List.of(
"id.keyword",
"shops.id.keyword",
"contractors.id.keyword",
"contracts.id.keyword");
}
private List<String> fields() {
return List.of(
"id",
"email",
"shops.id",
"shops.locationUrl",
"shops.detailsName",
"shops.contractId",
"shops.detailsDescription");
}
private Query searchBestFields(String text, List<String> fields) {
return new Query(new MultiMatchQuery.Builder()
.fields(fields)
.query(text)
.type(TextQueryType.BestFields)
.operator(Operator.Or)
.build());
}
private Query searchPhrasePrefix(String text, List<String> fields) {
return new Query(new MultiMatchQuery.Builder()
.fields(fields)
.query(text)
.type(TextQueryType.PhrasePrefix)
.operator(Operator.Or)
.build());
}
}

View File

@ -24,7 +24,7 @@ import java.util.Optional;
@Setting(settingPath = "/settings/autocomplete-analyzer.json") @Setting(settingPath = "/settings/autocomplete-analyzer.json")
public class Party { public class Party {
@Id @Id
@Field(type = FieldType.Keyword) @Field(type = FieldType.Text, analyzer = "autocomplete", searchAnalyzer = "standard")
private String id; private String id;
@Field(type = FieldType.Text, analyzer = "autocomplete", searchAnalyzer = "standard") @Field(type = FieldType.Text, analyzer = "autocomplete", searchAnalyzer = "standard")
private String email; private String email;

View File

@ -14,7 +14,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType;
@AllArgsConstructor @AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class Shop { public class Shop {
@Field(type = FieldType.Keyword) @Field(type = FieldType.Text, analyzer = "autocomplete", searchAnalyzer = "standard")
private String id; private String id;
private Blocking blocking; private Blocking blocking;
private Suspension suspension; private Suspension suspension;

View File

@ -7,7 +7,8 @@ import dev.vality.damsel.deanonimus.SearchWalletHit;
import dev.vality.deanonimus.converter.SearchHitConverter; import dev.vality.deanonimus.converter.SearchHitConverter;
import dev.vality.deanonimus.converter.SearchHitShopConverter; import dev.vality.deanonimus.converter.SearchHitShopConverter;
import dev.vality.deanonimus.converter.SearchHitWalletConverter; import dev.vality.deanonimus.converter.SearchHitWalletConverter;
import dev.vality.deanonimus.db.SearchDao; import dev.vality.deanonimus.db.SearchByShopDao;
import dev.vality.deanonimus.db.SearchDaoImpl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.opensearch.client.opensearch.core.search.Hit; import org.opensearch.client.opensearch.core.search.Hit;
@ -25,7 +26,8 @@ public class DeanonimusServiceHandler implements DeanonimusSrv.Iface {
private final SearchHitConverter searchHitConverter; private final SearchHitConverter searchHitConverter;
private final SearchHitShopConverter searchHitShopConverter; private final SearchHitShopConverter searchHitShopConverter;
private final SearchHitWalletConverter searchHitWalletConverter; private final SearchHitWalletConverter searchHitWalletConverter;
private final SearchDao searchDao; private final SearchDaoImpl searchDao;
private final SearchByShopDao searchByShopDao;
@Override @Override
public List<SearchHit> searchParty(String text) { public List<SearchHit> searchParty(String text) {
@ -43,7 +45,7 @@ public class DeanonimusServiceHandler implements DeanonimusSrv.Iface {
@Override @Override
public List<SearchShopHit> searchShopText(String text) { public List<SearchShopHit> searchShopText(String text) {
log.info("Incoming request for shop with text: {}", text); log.info("Incoming request for shop with text: {}", text);
var searchHits = searchDao.searchParty(text); var searchHits = searchByShopDao.searchParty(text);
var parties = searchHits.hits().hits().stream().map(Hit::source).collect(toList()); var parties = searchHits.hits().hits().stream().map(Hit::source).collect(toList());
log.debug("Found for shop search parties: {}", parties); log.debug("Found for shop search parties: {}", parties);
log.info("Found for shop search parties: {}", parties.size()); log.info("Found for shop search parties: {}", parties.size());

View File

@ -23,7 +23,7 @@ import java.util.Map;
@Slf4j @Slf4j
@ExtendWith({KafkaContainerExtension.class, OpensearchContainerExtension.class}) @ExtendWith({KafkaContainerExtension.class, OpensearchContainerExtension.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@SpringBootTest @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class AbstractIntegrationTest { public abstract class AbstractIntegrationTest {
private static final String TOPIC_NAME = "mg-events-party"; private static final String TOPIC_NAME = "mg-events-party";

View File

@ -4,6 +4,7 @@ import dev.vality.damsel.deanonimus.SearchHit;
import dev.vality.damsel.deanonimus.SearchShopHit; import dev.vality.damsel.deanonimus.SearchShopHit;
import dev.vality.damsel.deanonimus.SearchWalletHit; import dev.vality.damsel.deanonimus.SearchWalletHit;
import dev.vality.deanonimus.domain.Party; import dev.vality.deanonimus.domain.Party;
import dev.vality.deanonimus.extension.OpensearchContainerExtension;
import dev.vality.deanonimus.handler.DeanonimusServiceHandler; import dev.vality.deanonimus.handler.DeanonimusServiceHandler;
import dev.vality.deanonimus.service.OpenSearchService; import dev.vality.deanonimus.service.OpenSearchService;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -15,9 +16,12 @@ import org.opensearch.client.opensearch.indices.DeleteIndexRequest;
import org.opensearch.client.opensearch.indices.ExistsRequest; import org.opensearch.client.opensearch.indices.ExistsRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.core.io.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import static dev.vality.deanonimus.constant.OpenSearchConstants.PARTY_INDEX; import static dev.vality.deanonimus.constant.OpenSearchConstants.PARTY_INDEX;
@ -28,6 +32,9 @@ public class ReadTest extends AbstractIntegrationTest {
@Value("${data.response.limit}") @Value("${data.response.limit}")
Integer responseLimit; Integer responseLimit;
@Value("classpath:index_request.json")
Resource indexModel;
@Autowired @Autowired
OpenSearchService openSearchService; OpenSearchService openSearchService;
@ -37,6 +44,10 @@ public class ReadTest extends AbstractIntegrationTest {
@Autowired @Autowired
DeanonimusServiceHandler deanonimusServiceHandler; DeanonimusServiceHandler deanonimusServiceHandler;
@Autowired
TestRestTemplate restTemplate;
private static final String PARTY = "party"; private static final String PARTY = "party";
private static final String SHOP = "shop"; private static final String SHOP = "shop";
private static final String EMAIL = "email@mail.com"; private static final String EMAIL = "email@mail.com";
@ -54,6 +65,7 @@ public class ReadTest extends AbstractIntegrationTest {
if (indices.exists(new ExistsRequest.Builder().index(PARTY_INDEX).build()).value()) { if (indices.exists(new ExistsRequest.Builder().index(PARTY_INDEX).build()).value()) {
indices.delete(new DeleteIndexRequest.Builder().index(PARTY_INDEX).build()); indices.delete(new DeleteIndexRequest.Builder().index(PARTY_INDEX).build());
} }
createIndex();
} }
@Test @Test
@ -167,6 +179,108 @@ public class ReadTest extends AbstractIntegrationTest {
.anyMatch(shop -> shop.getDetails().getName().contains("S2P")))); .anyMatch(shop -> shop.getDetails().getName().contains("S2P"))));
} }
@Test
void searchShopTextByShopNames() {
var party1 = givenParty(PARTY + "id-1", EMAIL);
givenShop(party1, SHOP + "id-1", URL, "S2P_BRL");
var party2 = givenParty(PARTY + "id-2", EMAIL);
givenShop(party2, SHOP + "id-2", URL, "S2P_BRL");
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText("s2p");
assertFalse(searchHits.isEmpty());
assertEquals(2, searchHits.size());
var expected = Set.of(SHOP + "id-1", SHOP + "id-2");
assertTrue(searchHits.stream().allMatch(shopHit -> expected.contains(shopHit.getShop().getId())));
}
@Test
void searchShopTextByPartyId() {
var party = givenParty(PARTY, EMAIL);
givenShop(party, SHOP, URL, "S2P_BRL");
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText(PARTY);
assertFalse(searchHits.isEmpty());
assertEquals(1, searchHits.size());
assertTrue(searchHits.stream().anyMatch(shopHit -> shopHit.getParty().getId().equals(PARTY)));
}
@Test
void searchShopTextContainsPartyId() {
var party = givenParty("party-test-1", EMAIL);
givenShop(party, SHOP, URL, "S2P_BRL");
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText("test");
assertFalse(searchHits.isEmpty());
assertEquals(1, searchHits.size());
assertTrue(searchHits.stream().anyMatch(shopHit -> shopHit.getParty().getId().equals("party-test-1")));
}
@Test
void searchShopTextByContractorId() {
var party = givenParty(PARTY, EMAIL);
givenShop(party, SHOP, URL, "S2P_BRL");
givenRegisteredUserContractor(party, CONTRACTOR, EMAIL);
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText(CONTRACTOR);
assertFalse(searchHits.isEmpty());
assertEquals(1, searchHits.size());
assertTrue(searchHits.stream().anyMatch(shopHit -> shopHit.getShop().getId().equals(SHOP)));
}
@Test
void searchShopTextByContractId() {
var party = givenParty(PARTY, EMAIL);
givenShop(party, SHOP, URL, "S2P_BRL");
givenContract(party, CONTRACT, 123, "ДГ-123432", "Василий Пупкин");
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText(PARTY);
assertFalse(searchHits.isEmpty());
assertEquals(1, searchHits.size());
assertTrue(searchHits.stream().anyMatch(shopHit -> shopHit.getShop().getId().equals(SHOP)));
}
@Test
void searchShopTextByEmail() {
var party = givenParty(PARTY, EMAIL);
givenShop(party, SHOP, URL, "S2P_BRL");
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText(EMAIL);
assertFalse(searchHits.isEmpty());
assertEquals(1, searchHits.size());
assertTrue(searchHits.stream().anyMatch(shopHit -> shopHit.getShop().getId().equals(SHOP)));
}
@Test
void searchShopTextByPartyIdAndShopId() {
var party1 = givenParty("party-test-1", EMAIL);
givenShop(party1, "shop-id-1", URL, "S2P_BRL-1");
givenShop(party1, "shop-id-2", URL, "S2P_BRL-2");
var party2 = givenParty("party-id-2", EMAIL);
givenShop(party2, "shop-test-1", URL, "details-1");
givenShop(party2, "shop-none-2", URL, "details-2");
refreshIndices();
var searchHits = deanonimusServiceHandler.searchShopText("test");
assertFalse(searchHits.isEmpty());
assertEquals(3, searchHits.size());
var expected = Set.of("shop-id-1", "shop-id-2", "shop-test-1");
assertTrue(searchHits.stream().allMatch(shopHit -> expected.contains(shopHit.getShop().getId())));
}
@Test @Test
void searchShopTextByDiffShop() throws TException { void searchShopTextByDiffShop() throws TException {
Party party = givenParty(PARTY, EMAIL); Party party = givenParty(PARTY, EMAIL);
@ -195,6 +309,25 @@ public class ReadTest extends AbstractIntegrationTest {
.anyMatch(partySearchHit -> partySearchHit.getShop().getId().equals(SHOP))); .anyMatch(partySearchHit -> partySearchHit.getShop().getId().equals(SHOP)));
} }
@Test
void searchShopTextContainsShopIds() {
Party party1 = givenParty(PARTY + "id-1", EMAIL);
givenShop(party1, "test-id-1", URL);
Party party2 = givenParty(PARTY + "id-2", EMAIL);
givenShop(party2, "test-id-2", URL);
refreshIndices();
List<SearchShopHit> searchShopHits = deanonimusServiceHandler.searchShopText("test");
assertFalse(searchShopHits.isEmpty());
assertEquals(2, searchShopHits.size());
var expected = Set.of("test-id-1", "test-id-2");
assertTrue(searchShopHits.stream().allMatch(shopHit -> expected.contains(shopHit.getShop().getId())));
}
@Test @Test
void searchShopTextByShopUrl() throws TException { void searchShopTextByShopUrl() throws TException {
Party party = givenParty(PARTY, EMAIL); Party party = givenParty(PARTY, EMAIL);
@ -471,4 +604,12 @@ public class ReadTest extends AbstractIntegrationTest {
private void refreshIndices() { private void refreshIndices() {
client.indices().refresh(); client.indices().refresh();
} }
private void createIndex() {
var url = "http://" +
OpensearchContainerExtension.OPENSEARCH.getHost() + ":" +
OpensearchContainerExtension.OPENSEARCH.getFirstMappedPort() + "/" +
PARTY_INDEX;
restTemplate.put(url, indexModel);
}
} }

View File

@ -1,371 +0,0 @@
{
"party": {
"mappings": {
"properties": {
"blocking": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"contractors": {
"properties": {
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityActualAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityLegalName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityRegisteredAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityRegisteredNumber": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityTradingName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"legalEntity": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"partyId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"registeredUserEmail": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityActualAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityInn": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityPostAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRegisteredName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRegisteredNumber": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankAccount": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankBik": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankPostAccount": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"contracts": {
"properties": {
"contractorId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"legalAgreementId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"partyId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"paymentInstitutionId": {
"type": "long"
},
"status": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"termsId": {
"type": "long"
}
}
},
"email": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"shops": {
"properties": {
"accountCurrencyCode": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"accountGuarantee": {
"type": "long"
},
"accountPayout": {
"type": "long"
},
"accountSettlement": {
"type": "long"
},
"blocking": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"categoryId": {
"type": "long"
},
"contractId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"detailsDescription": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"detailsName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"locationUrl": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"payoutToolId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"suspension": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"suspension": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}

View File

@ -0,0 +1,375 @@
{
"settings": {
"index": {
"number_of_shards": 2,
"number_of_replicas": 1
}
},
"mappings": {
"properties": {
"blocking": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"contractors": {
"properties": {
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityActualAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityLegalName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityRegisteredAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityRegisteredNumber": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"internationalLegalEntityTradingName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"legalEntity": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"partyId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"registeredUserEmail": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityActualAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityInn": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityPostAddress": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRegisteredName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRegisteredNumber": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankAccount": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankBik": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"russianLegalEntityRussianBankPostAccount": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"contracts": {
"properties": {
"contractorId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"legalAgreementId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"partyId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"paymentInstitutionId": {
"type": "long"
},
"status": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"termsId": {
"type": "long"
}
}
},
"email": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"shops": {
"properties": {
"accountCurrencyCode": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"accountGuarantee": {
"type": "long"
},
"accountPayout": {
"type": "long"
},
"accountSettlement": {
"type": "long"
},
"blocking": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"categoryId": {
"type": "long"
},
"contractId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"detailsDescription": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"detailsName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"locationUrl": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"payoutToolId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"suspension": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"suspension": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}