Updated Documentation
This commit is contained in:
@@ -32,16 +32,16 @@
|
||||
|
||||
<example>
|
||||
<title>Setting up Elasticsearch repositories using Namespace</title>
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:repositories base-package="com.acme.repositories" />
|
||||
<elasticsearch:repositories base-package="com.acme.repositories" />
|
||||
</beans></programlisting>
|
||||
</example>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
@@ -71,16 +71,16 @@ http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.
|
||||
|
||||
<example>
|
||||
<title>Node Client using Namespace</title>
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:node-client id="client" local="true"" />
|
||||
<elasticsearch:node-client id="client" local="true"" />
|
||||
</beans> </programlisting>
|
||||
</example>
|
||||
</para>
|
||||
@@ -93,16 +93,16 @@ http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.
|
||||
</para>
|
||||
<example>
|
||||
<title>Spring Data Elasticsearch repositories using JavaConfig</title>
|
||||
<programlisting language="java">
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
|
||||
static class Config {
|
||||
<programlisting language="java">
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public ElasticsearchOperations elasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}</programlisting>
|
||||
@Bean
|
||||
public ElasticsearchOperations elasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}</programlisting>
|
||||
<para>
|
||||
The configuration above sets up an
|
||||
<classname>Embedded Elasticsearch Server</classname>
|
||||
@@ -127,27 +127,27 @@ http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.
|
||||
</para>
|
||||
<example>
|
||||
<title>Spring Data Elasticsearch repositories using JavaConfig</title>
|
||||
<programlisting language="java">class ElasticsearchTemplateProducer {
|
||||
<programlisting language="java">class ElasticsearchTemplateProducer {
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
public ElasticsearchOperations createElasticsearchTemplate() {
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
public ElasticsearchOperations createElasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(new EmbeddedElasticsearchServerFactory("classpath:com/acme/Elasticsearch"));
|
||||
}
|
||||
}
|
||||
|
||||
class ProductService {
|
||||
|
||||
private ProductRepository repository;
|
||||
private ProductRepository repository;
|
||||
|
||||
public Page<Product> findAvailableBookByName(String name, Pageable pageable) {
|
||||
return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
|
||||
}
|
||||
public Page<Product> findAvailableBookByName(String name, Pageable pageable) {
|
||||
return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setRepository(ProductRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
@Inject
|
||||
public void setRepository(ProductRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
@@ -195,12 +195,12 @@ class ProductService {
|
||||
Elasticsearch json query
|
||||
</para>
|
||||
<programlisting>
|
||||
{ "bool" : { "must" :
|
||||
{ "bool" :
|
||||
{ "must" :
|
||||
[
|
||||
{ "field" : {"name" : "?"} },
|
||||
{ "field" : {"price" : "?"} }
|
||||
]
|
||||
} }</programlisting>
|
||||
] } }</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
@@ -227,19 +227,7 @@ class ProductService {
|
||||
<code>findByNameAndPrice</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : [ {
|
||||
"field" : {
|
||||
"name" : "?"
|
||||
}
|
||||
}, {
|
||||
"field" : {
|
||||
"price" : "?"
|
||||
}
|
||||
} ]
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -250,19 +238,7 @@ class ProductService {
|
||||
<code>findByNameOrPrice</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"should" : [ {
|
||||
"field" : {
|
||||
"name" : "?"
|
||||
}
|
||||
}, {
|
||||
"field" : {
|
||||
"price" : "?"
|
||||
}
|
||||
} ]
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -273,15 +249,7 @@ class ProductService {
|
||||
<code>findByName</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"field" : {
|
||||
"name" : "?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : "?"}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -292,15 +260,7 @@ class ProductService {
|
||||
<code>findByNameNot</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must_not" : {
|
||||
"field" : {
|
||||
"name" : "?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -311,20 +271,7 @@ class ProductService {
|
||||
<code>findByPriceBetween</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"range" : {
|
||||
"price" : {
|
||||
"from" : ?,
|
||||
"to" : ?,
|
||||
"include_lower" : true,
|
||||
"include_upper" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -335,20 +282,7 @@ class ProductService {
|
||||
<code>findByPriceLessThan</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"range" : {
|
||||
"price" : {
|
||||
"from" : null,
|
||||
"to" : ?,
|
||||
"include_lower" : true,
|
||||
"include_upper" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -359,20 +293,7 @@ class ProductService {
|
||||
<code>findByPriceGreaterThan</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"range" : {
|
||||
"price" : {
|
||||
"from" : ?,
|
||||
"to" : null,
|
||||
"include_lower" : true,
|
||||
"include_upper" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -383,20 +304,7 @@ class ProductService {
|
||||
<code>findByPriceBefore</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"range" : {
|
||||
"price" : {
|
||||
"from" : null,
|
||||
"to" : ?,
|
||||
"include_lower" : true,
|
||||
"include_upper" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -407,21 +315,7 @@ class ProductService {
|
||||
<code>findByPriceAfter</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"range" : {
|
||||
"price" : {
|
||||
"from" : ?,
|
||||
"to" : null,
|
||||
"include_lower" : true,
|
||||
"include_upper" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</code>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -432,18 +326,7 @@ class ProductService {
|
||||
<code>findByNameLike</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"field" : {
|
||||
"name" : {
|
||||
"query" : "?*",
|
||||
"analyze_wildcard" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -454,18 +337,7 @@ class ProductService {
|
||||
<code>findByNameStartingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"field" : {
|
||||
"name" : {
|
||||
"query" : "?*",
|
||||
"analyze_wildcard" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -476,18 +348,7 @@ class ProductService {
|
||||
<code>findByNameEndingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"field" : {
|
||||
"name" : {
|
||||
"query" : "*?",
|
||||
"analyze_wildcard" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -498,18 +359,7 @@ class ProductService {
|
||||
<code>findByNameContaining</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{
|
||||
"bool" : {
|
||||
"must" : {
|
||||
"field" : {
|
||||
"name" : {
|
||||
"query" : "*?*",
|
||||
"analyze_wildcard" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</code>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" : "*?*","analyze_wildcard" : true}}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
Filter Builder improves query speed.
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
SearchQuery searchQuery = new SearchQuery();
|
||||
searchQuery.setElasticsearchQuery(matchAllQuery());
|
||||
searchQuery.setElasticsearchFilter(boolFilter().must(termFilter("id", documentId)));
|
||||
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
|
||||
</programlisting>
|
||||
<programlisting language="java">
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
SearchQuery searchQuery = new SearchQuery();
|
||||
searchQuery.setElasticsearchQuery(matchAllQuery());
|
||||
searchQuery.setElasticsearchFilter(boolFilter().must(termFilter("id", documentId)));
|
||||
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="solr.misc">
|
||||
<title>Miscellaneous Solr Operation Support</title>
|
||||
<abstract>
|
||||
<para>
|
||||
This chapter covers additional support for Solr operations (such as
|
||||
faceting) that cannot be directly accessed via the repository
|
||||
interface.
|
||||
It is recommended to add those operations as custom
|
||||
implementation as
|
||||
described in
|
||||
<xref linkend="repositories.custom-implementations" />
|
||||
.
|
||||
</para>
|
||||
</abstract>
|
||||
<section id="solr.misc.partialUpdates">
|
||||
<title>Partial Updates</title>
|
||||
<para>
|
||||
PartialUpdates can be done using
|
||||
<classname>PartialUpdate</classname>
|
||||
which implements
|
||||
<interfacename>Update</interfacename>
|
||||
.
|
||||
<note>
|
||||
With Solr 4.0.0 it is not possible to update mulitvalue fields.
|
||||
</note>
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">PartialUpdate update = new PartialUpdate("id", "123");
|
||||
update.add("name", "updated-name");
|
||||
solrTemplate.saveBean(update);</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
<section id="solr.misc.projection">
|
||||
<title>Projection</title>
|
||||
<para>
|
||||
Projections can be applied via
|
||||
<interfacename>@Query</interfacename>
|
||||
using the fields value.
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">@Query(fields = { "name", "id" })
|
||||
List<ProductBean> findByNameStartingWith(String name);</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
<section id="solr.misc.faceting">
|
||||
<title>Faceting</title>
|
||||
<para>
|
||||
Faceting cannot be directly applied using the
|
||||
<interfacename>SolrRepository</interfacename>
|
||||
but the
|
||||
<classname>SolrTemplate</classname>
|
||||
holds support for this feature.
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">FacetQuery query = new SimpleFacetQuery(new Criteria(Criteria.WILDCARD).expression(Criteria.WILDCARD))
|
||||
.setFacetOptions(new FacetOptions().addFacetOnField("name").setFacetLimit(5));
|
||||
FacetPage<Product> page = solrTemplate.queryForFacetPage(query, Product.class);</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
Facets on fields can also be defined using
|
||||
<interfacename>@Facet</interfacename>
|
||||
. Please mind that the result will be a
|
||||
<classname>FacetPage</classname>
|
||||
.
|
||||
<programlisting language="java">@Query(value = "*:*")
|
||||
@Facet(fields = { "name" }, limit = 5)
|
||||
FacetPage<Product> findAllFacetOnPopularity(Pageable page);</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
<section id="solr.misc.filter">
|
||||
<title>Filter Query</title>
|
||||
<para>
|
||||
Filter Queries improve query speed. It is recommended to
|
||||
implement
|
||||
geospatial search as filter query.
|
||||
<note>
|
||||
Please note that in solr, unless otherwise specified, all units of
|
||||
distance are kilometers and points are in degrees of
|
||||
latitude,longitude.
|
||||
</note>
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">Query query = new SimpleQuery(new Criteria("category").is("supercalifragilisticexpialidocious"));
|
||||
FilterQuery fq = new SimpleFilterQuery(new Criteria("store")
|
||||
.near(new GeoLocation(48.305478, 14.286699), new Distance(5)));
|
||||
query.addFilterQuery(fq);</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
Simple filter queries can also be defined using
|
||||
<interfacename>@Query</interfacename>
|
||||
.
|
||||
</para>
|
||||
<programlisting language="java">@Query(value = "*:*", filters = { "inStock:true", "popularity:[* TO 3]" })
|
||||
List<ProductBean> findAllFilterAvailableTrueAndPopularityLessThanEqual3();</programlisting>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
|
||||
|
||||
<elasticsearch:node-client id="client" local="true"/>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
|
||||
|
||||
<elasticsearch:node-client id="client" local="true"/>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
|
||||
|
||||
<elasticsearch:node-client id="client" local="true"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user