Utiliser l'API Java Elasticsearch (enregistrement BulkRequest) [Notes supplémentaires]

Elasticsearch vous permet d'utiliser l'API Java.

Document officiel de l'API Java Elasticsearch

C'est assez pratique, mais il semble qu'il n'y ait pas beaucoup d'informations disponibles, alors je l'ai résumé.

[2018/01/12] Addendum

Le TransportClient '' utilisé dans cet article est obsolète à partir de la prochaine version majeure 7 et sera supprimé dans 8. Par conséquent, il est recommandé de migrer vers Client REST de haut niveau ''. Veuillez consulter la section des commentaires pour plus de détails. Merci d'avoir souligné, johtani.

Exigences

Je voudrais le faire avec une telle image.

Environnement de développement

Structure de données

Dans le cas de RDB, les informations sur la succursale et le titre du livre sont stockées dans des TBL séparés, et des TBL de vente sont créés et connectés. Cependant, dans le cas d'ELS, il s'agit de données pour chaque ligne. Enregistrez plusieurs enregistrements. Je pense que les enregistrements ELS sont faciles à faire si vous avez une image de type vue.

Le taux (pondération) est-il caractéristique de cet enregistrement? Le classement est généralement le plus élevé et le classement diminue à mesure que le nombre augmente. Cependant, si vous essayez d'afficher ce classement sur l'axe Y du graphique de la ligne de pliage, vous devez afficher la valeur au fur et à mesure que la valeur sur l'axe Y monte, ce qui est le contraire de la valeur habituelle, difficile à exprimer avec ELS. est. Référence (ou plutôt ma question précédente): Affichage du classement sur un graphique en ligne brisée

Par conséquent, le taux est le résultat de la conversion de la valeur de classement sous forme de pondération afin que le graphique puisse être affiché facilement.

Méthode de calcul des tarifs:(Classement total) - (Propre valeur de classement) + 1

Si le nombre total de classements change, l'affichage du graphique changera, il sera donc 100 ou 1000, et utilisera toujours une valeur fixe.

Créez un JSON qui peut être importé dans ELS par n'importe quelle méthode.

JSON

branch	title	author	genre	ranking	rate	execDate
Shinjuku Titre A Auteur Ahn comic-girl	1	3	2018/01/11T13:00:00+09:00
Shinjuku Title B Auteur et plus tard bande dessinée-male	2	2	2018/01/11T13:00:00+09:00
Shinjuku Titre C Auteur U bande dessinée-girl	3	1	2018/01/11T13:00:00+09:00
Marunouchi Titre C Auteur U bande dessinée-girl	1	3	2018/01/11T13:00:00+09:00
Marunouchi Titre A Auteur Ahn comic-girl	2	2	2018/01/11T13:00:00+09:00
Marunouchi Titre D Bande dessinée de vêtements de l'auteur-boy	3	1	2018/01/11T13:00:00+09:00
Shinagawa Title B Auteur et plus tard bande dessinée-male	1	3	2018/01/11T13:00:00+09:00
Shinagawa Titre C Auteur U bande dessinée-girl	2	2	2018/01/11T13:00:00+09:00
Shinagawa Title E Auteur à la bande dessinée-femail	3	1	2018/01/11T13:00:00+09:00

ranking.json


[{"branch":"Shinjuku","title":"Titre A","author":"Auteur Ahn","genre":"comic-girl","ranking":1,"rate":3,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Shinjuku","title":"Titre B","author":"De l'auteur","genre":"comic-male","ranking":2,"rate":2,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Shinjuku","title":"Titre C","author":"Auteur U","genre":"comic-girl","ranking":3,"rate":1,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Marunouchi","title":"Titre C","author":"Auteur U","genre":"comic-girl","ranking":1,"rate":3,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Marunouchi","title":"Titre A","author":"Auteur Ahn","genre":"comic-girl","ranking":2,"rate":2,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Marunouchi","title":"Titre D","author":"Vêtements d'auteur","genre":"comic-boy","ranking":3,"rate":1,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Shinagawa","title":"Titre B","author":"De l'auteur","genre":"comic-male","ranking":1,"rate":3,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Shinagawa","title":"Titre C","author":"Auteur U","genre":"comic-girl","ranking":2,"rate":2,"execDate":"2018/01/11T13:00:00+09:00"},{"branch":"Shinagawa","title":"Titre E","author":"Chez l'auteur","genre":"comic-femail","ranking":3,"rate":1,"execDate":"2018/01/11T13:00:00+09:00"}]

Bean

Nous allons également créer un bean d'information de classement correspondant à cela.

RankingDataBean.java


public class RankingDataBean extends ElsDataBaseBean {

	//Nom de la filiale
	private String branch;
	//Titre de livre
	private String title;
	//Nom de l'auteur
	private String author;
	//Genre
	private String genre;
	//Classement
	private int ranking;
	//taux
	private int rate;
	//Date d'inscription
	private Date execDate;
	
	(Abréviation)
}

La caractéristique ici est qu'il hérite d'ElsDataBaseBean. Le contenu est comme ça.

ElsDataBaseBean.java


public class ElsDataBaseBean {
	//indice
	private String index;

	(Abréviation)
}

Je n'ai que l'index moi-même. Nous allons créer un importateur afin que tout bean qui hérite de ce bean puisse être enregistré.

Processus d'importation vers ELS

ElsImporter.java


/**
 *Importez des données dans ELS avec Bulk
 */
public class ElsImporter<T extends ElsDataBaseBean> {

	private static Logger logger = LoggerFactory.getLogger(ElsImporter.class);

	//Format d'index année / mois(yyyyMM)
	private static DateTimeFormatter YM_INDEX_FORMATTER;

	//Diverses informations de réglage
	SettingBaseBean setting;

	//Classe de données à importer
	Class<T> clazz;

	/**
	 *constructeur
	 * @param setting Diverses informations de réglage
	 * @param clazz Classe de données à importer
	 */
	public ElsImporter(SettingBaseBean setting, Class<T> clazz) {
		this.setting = setting;
		this.clazz = clazz;

		YM_INDEX_FORMATTER = DateTimeFormatter.ofPattern(setting.getElasticearch().getIndexYmFormat());
	}

	/**
	 *Effectuer l'importation
	 */
	public boolean execute() throws Exception {

		logger.info("Processus d'importation ElsImporter lancé-----------------------------------------");

		//Créer un client pour gérer ELS en Java
		// setting.getElasticearch().getAddress():adresse IP
		// setting.getElasticearch().getPort():numéro de port(Généralement 9300)
		TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
				.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(
						setting.getElasticearch().getAddress()), setting.getElasticearch().getPort()));

		//préparation en vrac
		BulkRequestBuilder bulkRequest = client.prepareBulk();

		//Préparation Gson
		// setting.getElasticearch().getExecDateFormat(): 
		//Format de la date d'inscription(yyyy/MM/dd'T'HH:mm:ss+09:00)
		Gson gson = new GsonBuilder().setDateFormat(setting.getElasticearch().getExecDateFormat()).create();

		//Ciblez tous les fichiers dans le répertoire contenant JSON
		File dir = new File(setting.getRootDir(), setting.getSubDir().getJsonDir());
		for (File file : dir.listFiles()) {

			logger.debug("■■ Import: "+ file.getName());

			//Convertir les données JSON en liste
			List<T> list = gson.fromJson(FileUtils.readFileToString(file, "UTF-8"), new ListOfSomething<T>(clazz));

			//Obtenez les informations de classement une par une et ajoutez-les à l'ensemble
			for (T data : list) {
				//Index des destinations d'enregistrement
				// setting.getElasticearch().getIndex():Index ELS(partie commune)
				// setting.getNow():LocalDateTime au moment de l'exécution du traitement
				//Exemple 1: setting.getElasticearch().getIndex()	: ranking
				//      data.getIndex()						: comic-girl
				//      setting.getNow()					: 2018/01/18 12:00:00
				//Générer un index: ranking-comic-girl-201801
				//Exemple 2: setting.getElasticearch().getIndex()	: ranking
				//      data.getIndex()						: null
				//      setting.getNow()					: 2018/01/18 12:00:00
				//Générer un index: ranking-201801
				String index;
				if (StringUtils.isEmpty(data.getIndex())) {
					//Version non sous-indexée
					index = setting.getElasticearch().getIndex()
							+ "-" + YM_INDEX_FORMATTER.format(setting.getNow());
				}
				else {
					//Version sous-indexée
					index = setting.getElasticearch().getIndex()
							+ "-" + data.getIndex()
							+ "-" + YM_INDEX_FORMATTER.format(setting.getNow());
				}
			
				//Ajouter des données au format JSON à Bulk
				// setting.getElasticearch().getType():Type ELS
				bulkRequest.add(client.prepareIndex(index
						, setting.getElasticearch().getType())
					.setSource(gson.toJson(data), XContentType.JSON));
			}
		}

		//Exécution en masse
		BulkResponse bulkResponse = bulkRequest.execute().get();

		//Bulk échoue-t-il?(Vrai si échoué)
		if (bulkResponse.hasFailures()) {
			logger.error("ElsImporter en masse a échoué");

			//Quittez le client
			client.close();

			return false;
		}

		logger.info("Processus d'importation ElsImporter terminé-----------------------------------------");

		//Quittez le client
		client.close();

		return true;
	}

	/**
	 *Convertir les objets de la liste au type spécifié avec Gson
	 */
	class ListOfSomething<X> implements ParameterizedType {

	    private Class<?> wrapped;

	    public ListOfSomething(Class<X> wrapped) {
	        this.wrapped = wrapped;
	    }

	    public Type[] getActualTypeArguments() {
	        return new Type[] {wrapped};
	    }

	    public Type getRawType() {
	        return List.class;
	    }

	    public Type getOwnerType() {
	        return null;
	    }

	}
}

Référence: Java Type Generic as Argument for GSON

Les informations de classe de données elles-mêmes à importer ne sont pas stockées dans l'importateur. Comme il ne correspond qu'à des informations génériques et de classe, il peut être détourné vers d'autres informations que ces informations de classement. elsdatabasebeanEu dansindexAgit comme un sous-index. kibanaPour afficher avecjava-apiJe pense qu'il est bon de le donner en fonction de la granularité acquise en. La granularité d'index ELS par défaut est logstash, mais c'est une bonne idée d'en tenir compte également, en fonction de la durée pendant laquelle vous l'essayez souvent.

exec.java


ElsImporter<RankingDataBean> importer 
	= new ElsImporter<RankingDataBean>(setting, RankingDataBean.class);
boolean result = importer.execute();

L'appel se fait de cette façon. rankingdatabeanC'est un peu étrange de lister 3 lieux, mais j'ai abandonné car il supporte gson.

Impressions

J'ai fait de mon mieux pour rendre le processus d'importation des demandes groupées aussi polyvalent que possible. À partir de la prochaine fois, j'aimerais approfondir ces données enregistrées.

Recommended Posts

Utiliser l'API Java Elasticsearch (enregistrement BulkRequest) [Notes supplémentaires]
Utilisation de l'API Java Elasticsearch (agrégation)