I am mainly referring to lucene's practice book. However, I have found some errors in the Chinese version. As a result, the program does not give the desired results. I still need to refer to the api documentation. Lucene3.X implements custom sorting. It mainly inherits the class FieldComparatorSource and the subclass of FieldComparator. 1. inherit FieldComparatorSource and must implement the abstract method newComparator. 2. inherit FieldComparator. The following six abstract methods must be implemented: compare (int, int) Compare a hit at 'slot a' with hit' slot B '. setBottom (int) This method is called by FieldValueHitQueue to sort y the FieldComparator of the current weakest ("bottom") slot. note that this slot may not hold the weakest value according to your comparator, in cases where your comparator is not the primary one (ie, is only used to break ties from Comparators before it ). compareBottom (int) Compare a new hit (docID) against the "weakest" (bottom) entry in the queue. copy (int, int) installa new hit into the priority queue. the FieldValueHitQueue CILS this method when a new hit is competitive. setNextReader (org. apache. lucene. index. indexReader, int) Invoked when the search is switching to the next segment. you may need to update internal state Of the comparator, for example retrieving new values from the FieldCache. value (int) Return the sort value stored in the specified slot. this is only called at the end of the search, in order to populate FieldDoc. fields when returning the top results. the above method description is taken from the api documentation. For details, refer to the api. The example is a simple example in the book. The matching results are sorted by the user's address (two-dimensional) to find the nearest restaurant. Each location specifies three domains, I .e., place names, two-dimensional coordinates x and y, and the type of the location. The specific implementation code is as follows: [java] package org. apache. lucene. demo; import java. io. IOException; import org.apache.e.doc ument. field; import org. apache. lucene. index. indexReader; import org. apache. lucene. search. fieldCache; import org. apache. lucene. search. fieldComparator; import org. apache. lucene. search. fieldComparatorSource; import org. apache. lucene. search. sortField; public class DistanceComparatorSource extends F IeldComparatorSource {private int x; private int y; public DistanceComparatorSource (int x, int y) {this. x = x; this. y = y ;}@ Override public FieldComparator <?> NewComparator (String arg0, int arg1, int arg2, boolean arg3) throws IOException {// TODO Auto-generated method stub return new DistanceSourceLookupComparator (arg0, arg1 );} private class extends FieldComparator {private int [] xDoc, yDoc; private float [] values; private float bottom; String fieldName; public DistanceSourceLookupComparator (String fieldName, int numHits) {values = new float [numHits]; this. fieldName = fieldName;} @ Override public int compare (int arg0, int arg1) {// TODO Auto-generated method stub if (values [arg0]> values [arg1]) return 1; if (values [arg0] <values [arg1]) return-1; return 0;} private float getDistance (int doc) {int deltax = xDoc [doc]-x; int deltay = yDoc [doc]-y; return (float) Math. sqrt (deltax * deltax + deltay * deltay);} @ Override public int compareBottom (int arg0) throws IOException {// TODO Auto-generated method stub float distance = getDistance (arg0 ); if (bottom <distance) return-1; if (bottom> distance) return 1; return 0 ;}@ Override public void copy (int arg0, int arg1) throws IOException {// TODO Auto-generated method stub values [arg0] = getDistance (arg1);} @ Override public void setBottom (int arg0) {// TODO Auto-generated method stub bottom = values [arg0];} @ Override public void setNextReader (IndexReader arg0, int arg1) // <span style = "color: # cc0000; "> An error occurred while reading the next segment. According to api understanding, the following implementation gets the correct result </span> throws IOException {// TODO Auto-generated method stub String [] temp = FieldCache. DEFAULT. getStrings (arg0, "location"); xDoc = new int [temp. length]; yDoc = new int [temp. length]; for (int I = 0; I <temp. length; I ++) {String [] str = temp [I]. split (","); xDoc [I] = Integer. parseInt (str [0]); yDoc [I] = Integer. parseInt (str [1]); }}@ Override public Object value (int arg0) {// TODO Auto-generated method stub return new Float (values [arg0]);} public int sortType () {return SortField. CUSTOM;} public String toString () {return "Distance from (" + x + "," + y + ")";}}} the following is a specific program for testing and running the sorting result: [java] package org. apache. lucene. demo; import java. io. IOException; import javax. crypto. sealedObject; import org. apache. lucene. analysis. whitespaceAnalyzer; import org.apache.w.e.doc ument. document; import org.apache.e.doc ument. field; import org.apache.e.doc ument. fieldSelectorResult; import org. apache. lucene. index. corruptIndexException; import org. apache. lucene. index. indexWriter; import org. apache. lucene. index. term; import org. apache. lucene. search. fieldDoc; import org. apache. lucene. search. indexSearcher; import org. apache. lucene. search. query; import org. apache. lucene. search. scoreDoc; import org. apache. lucene. search. searcher; import org. apache. lucene. search. sort; import org. apache. lucene. search. sortField; import org. apache. lucene. search. termQuery; import org. apache. lucene. search. topDocs; import org. apache. lucene. search. topFieldDocs; import org. apache. lucene. store. lockObtainFailedException; import org. apache. lucene. store. RAMDirectory; public class DistanceSortingTest {/*** @ param args * @ throws IOException * @ throws handler * @ throws CorruptIndexException */public static void main (String [] args) throws CorruptIndexException, lockObtainFailedException, IOException {// TODO Auto-generated method stub RAMDirectory directory = new RAMDirectory (); IndexWriter indexWriter = new IndexWriter (directory, new WhitespaceAnalyzer (), IndexWriter. maxFieldLength. UNLIMITED); addPoint (indexWriter, "El charro", "restaurant", 1, 2); addPoint (indexWriter, "Cafe Poca Cosa", "restaurant", 5, 9 ); addPoint (indexWriter, "Los Betos", "restaurant", 9, 6); addPoint (indexWriter, "Nico's Toco Shop", "restaurant", 3, 8 ); indexWriter. close (); Searcher searcher = new IndexSearcher (directory); Query query = new TermQuery (new Term ("type", "restaurant ")); sort sort = new Sort (new SortField ("location", new DistanceComparatorSource (10, 10); TopFieldDocs topDocs = searcher. search (query, null, 5, sort); ScoreDoc [] docs = topDocs. scoreDocs; // FieldDoc fieldDoc = (FieldDoc) topDocs. scoreDocs [0]; // System. out. println (fieldDoc. fields [0]); for (ScoreDoc doc: docs) {FieldDoc fieldDoc2 = (FieldDoc) doc; Document document = searcher.doc(doc.doc); System. out. println (document. get ("name");} System. out. println (Math. sqrt (17);} private static void addPoint (IndexWriter writer, String name, String type, int x, int y) throws CorruptIndexException, IOException {Document document = new Document (); document. add (new Field ("name", name, Field. store. YES, Field. index. NOT_ANALYZED); document. add (new Field ("type", type, Field. store. YES, Field. index. NOT_ANALYZED); document. add (new Field ("location", x + "," + y, Field. store. YES, Field. index. NOT_ANALYZED); writer. addDocument (document) ;}} running result: 4.1231055Los Betos5.0990195Cafe Poca Cosa7.28011Nico's Toco Shop12.0415945El charro