/* Extract doc IDs from an ES shard backup (a Lucene index) Copyright (c) 2025 Internet Archive Author: Amin Bandali This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import java.io.IOException; import java.nio.file.Paths; import java.util.Arrays; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.document.Document; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.UnicodeUtil; public class GetIDS { public static void main(String[] args) throws IOException { Directory indexDirectory = FSDirectory.open(Paths.get("/esdata/bck/16/index")); IndexReader reader = DirectoryReader.open(indexDirectory); IndexSearcher searcher = new IndexSearcher(reader); MatchAllDocsQuery query = new MatchAllDocsQuery(); int maxHits = reader.numDocs(); TopDocs topDocs = searcher.search(query, maxHits); // System.out.println("Total documents found: " + topDocs.totalHits.value); for (ScoreDoc scoreDoc : topDocs.scoreDocs) { Document doc = searcher.doc(scoreDoc.doc); // System.out.println("Document index: " + scoreDoc.doc); for (IndexableField field : doc.getFields()) { String name = field.name(); if (name.equals("_id")) { // String stored = String.valueOf(field.fieldType().stored()); String type = "string"; String value = field.stringValue(); if (value == null) { Number num = field.numericValue(); if (num != null) { type = "numeric"; value = num.toString(); } else { BytesRef bin = field.binaryValue(); if (bin != null) { type = "binary"; // based on BytesRef.utf8ToString() // for some reason, the first byte is always -1 ??? final char[] arr = new char[bin.length]; int len; int offset = bin.offset + 1; int length = bin.length - 1; try { len = UnicodeUtil.UTF8toUTF16(bin.bytes, offset, length, arr); } catch(ArrayIndexOutOfBoundsException e) { String err = "error aioob: bytes: %s (%s), offset: %d, length: %d"; System.err.println(String.format(err, bin.bytes, Arrays.toString(bin.bytes), offset, length)); break; } value = new String(arr, 0, len); } else { type = "unknown"; } } } // System.out.println(value + " (type: " + type + ")"); System.out.println(value); } } } reader.close(); indexDirectory.close(); } }