Files
opensearch-pyd/example/load.py
T

182 lines
5.7 KiB
Python
Raw Normal View History

2013-12-09 03:17:32 +01:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from os.path import dirname, basename, abspath
from datetime import datetime
import logging
import sys
import argparse
2013-12-09 03:17:32 +01:00
import git
from elasticsearch import Elasticsearch
from elasticsearch.exceptions import TransportError
2013-12-09 03:17:32 +01:00
from elasticsearch.helpers import bulk, streaming_bulk
2019-05-10 09:16:33 -06:00
2013-12-09 03:17:32 +01:00
def create_git_index(client, index):
# we will use user on several places
user_mapping = {
2019-05-10 09:16:33 -06:00
"properties": {
"name": {"type": "text", "fields": {"keyword": {"type": "keyword"}}}
}
}
create_index_body = {
2019-05-10 09:16:33 -06:00
"settings": {
# just one shard, no replicas for testing
"number_of_shards": 1,
"number_of_replicas": 0,
# custom analyzer for analyzing file paths
"analysis": {
"analyzer": {
"file_path": {
"type": "custom",
"tokenizer": "path_hierarchy",
"filter": ["lowercase"],
}
}
},
},
"mappings": {
2019-05-11 09:41:48 -06:00
"properties": {
"repository": {"type": "keyword"},
"author": user_mapping,
"authored_date": {"type": "date"},
"committer": user_mapping,
"committed_date": {"type": "date"},
"parent_shas": {"type": "keyword"},
"description": {"type": "text", "analyzer": "snowball"},
"files": {"type": "text", "analyzer": "file_path", "fielddata": True},
2013-12-09 03:17:32 +01:00
}
2019-05-10 09:16:33 -06:00
},
}
# create empty index
try:
2019-05-10 09:16:33 -06:00
client.indices.create(index=index, body=create_index_body)
2016-12-06 12:33:35 +01:00
except TransportError as e:
# ignore already existing index
2019-05-11 09:41:48 -06:00
if e.error == "resource_already_exists_exception":
pass
else:
raise
2013-12-09 03:17:32 +01:00
2019-05-10 09:16:33 -06:00
def parse_commits(head, name):
2013-12-09 03:17:32 +01:00
"""
Go through the git repository log and generate a document per commit
containing all the metadata.
"""
for commit in head.traverse():
2013-12-09 03:17:32 +01:00
yield {
2019-05-10 09:16:33 -06:00
"_id": commit.hexsha,
"repository": name,
"committed_date": datetime.fromtimestamp(commit.committed_date),
"committer": {
"name": commit.committer.name,
"email": commit.committer.email,
2013-12-09 03:17:32 +01:00
},
2019-05-10 09:16:33 -06:00
"authored_date": datetime.fromtimestamp(commit.authored_date),
"author": {"name": commit.author.name, "email": commit.author.email},
"description": commit.message,
"parent_shas": [p.hexsha for p in commit.parents],
2013-12-09 03:17:32 +01:00
# we only care about the filenames, not the per-file stats
2019-05-10 09:16:33 -06:00
"files": list(commit.stats.files),
"stats": commit.stats.total,
2013-12-09 03:17:32 +01:00
}
2019-05-10 09:16:33 -06:00
def load_repo(client, path=None, index="git"):
2013-12-09 03:17:32 +01:00
"""
Parse a git repository with all it's commits and load it into elasticsearch
using `client`. If the index doesn't exist it will be created.
"""
path = dirname(dirname(abspath(__file__))) if path is None else path
repo_name = basename(path)
repo = git.Repo(path)
create_git_index(client, index)
# we let the streaming bulk continuously process the commits as they come
# in - since the `parse_commits` function is a generator this will avoid
# loading all the commits into memory
for ok, result in streaming_bulk(
2019-05-10 09:16:33 -06:00
client,
parse_commits(repo.refs.master.commit, repo_name),
index=index,
chunk_size=50, # keep the batch sizes small for appearances only
):
2013-12-09 03:17:32 +01:00
action, result = result.popitem()
2019-05-10 09:16:33 -06:00
doc_id = "/%s/doc/%s" % (index, result["_id"])
2013-12-09 03:17:32 +01:00
# process the information from ES whether the document has been
# successfully indexed
if not ok:
2019-05-10 09:16:33 -06:00
print("Failed to %s document %s: %r" % (action, doc_id, result))
2013-12-09 03:17:32 +01:00
else:
print(doc_id)
# we manually update some documents to add additional information
UPDATES = [
{
2019-05-11 09:41:48 -06:00
"_type": "_doc",
2019-05-10 09:16:33 -06:00
"_id": "20fbba1230cabbc0f4644f917c6c2be52b8a63e8",
"_op_type": "update",
"doc": {"initial_commit": True},
2013-12-09 03:17:32 +01:00
},
{
2019-05-11 09:41:48 -06:00
"_type": "_doc",
2019-05-10 09:16:33 -06:00
"_id": "ae0073c8ca7e24d237ffd56fba495ed409081bf4",
"_op_type": "update",
"doc": {"release": "5.0.0"},
2013-12-09 03:17:32 +01:00
},
]
2019-05-10 09:16:33 -06:00
if __name__ == "__main__":
2013-12-09 03:17:32 +01:00
# get trace logger and set level
2019-05-10 09:16:33 -06:00
tracer = logging.getLogger("elasticsearch.trace")
2013-12-09 03:17:32 +01:00
tracer.setLevel(logging.INFO)
2019-05-10 09:16:33 -06:00
tracer.addHandler(logging.FileHandler("/tmp/es_trace.log"))
2013-12-09 03:17:32 +01:00
parser = argparse.ArgumentParser()
parser.add_argument(
2019-05-10 09:16:33 -06:00
"-H",
"--host",
action="store",
default="localhost:9200",
2019-05-10 09:16:33 -06:00
help="The elasticsearch host you wish to connect to. (Default: localhost:9200)",
)
parser.add_argument(
2019-05-10 09:16:33 -06:00
"-p",
"--path",
action="store",
default=None,
2019-05-10 09:16:33 -06:00
help="Path to git repo. Commits used as data to load into Elasticsearch. (Default: None",
)
args = parser.parse_args()
2013-12-09 03:17:32 +01:00
# instantiate es client, connects to localhost:9200 by default
es = Elasticsearch(args.host)
2013-12-09 03:17:32 +01:00
# we load the repo and all commits
load_repo(es, path=args.path)
2013-12-09 03:17:32 +01:00
# run the bulk operations
2019-05-10 09:16:33 -06:00
success, _ = bulk(es, UPDATES, index="git")
print("Performed %d actions" % success)
2013-12-09 03:17:32 +01:00
# we can now make docs visible for searching
2019-05-10 09:16:33 -06:00
es.indices.refresh(index="git")
2013-12-09 03:17:32 +01:00
# now we can retrieve the documents
2019-05-11 09:41:48 -06:00
initial_commit = es.get(index="git", id="20fbba1230cabbc0f4644f917c6c2be52b8a63e8")
2019-05-10 09:16:33 -06:00
print(
"%s: %s" % (initial_commit["_id"], initial_commit["_source"]["committed_date"])
)
2013-12-09 03:17:32 +01:00
# and now we can count the documents
2019-05-10 09:16:33 -06:00
print(es.count(index="git")["count"], "documents in index")