9

次のような注釈が付けられた pojo があります。

@Document
class Car {

  @Id
  String id ;

  @Indexed
  String manufacturer ;

}

そして、私はMongoTemplatemongoに挿入するために使用しています。コレクション名を指定せずに挿入すると、すべて正常に動作します。ただし、コレクション名を指定すると、それ以外のインデックスは作成されません_id

次の理由により、コレクション名を手動で指定できるようにする必要があります。

  • の異なるサブクラスがCar同じコレクションになるようにする必要があります
  • Cars毎年分のを別のコレクションに保管したい

ensureIndex()自分自身を手動で呼び出す必要がありますか? @Indexedもしそうなら、私の注釈を使ってそれを行う方法はありますか? 保存しようとしている実際のオブジェクトは、「車」よりもはるかに複雑です

4

4 に答える 4

5

残念ながらMongoTemplate機能

public void insert(Object objectToSave, String collectionName)

オブジェクトの保存のみに使用しcollectionName、注釈付きインデックスの作成には使用しません。オブジェクトが保存操作に渡された場合、アプリケーション イベント リスナーMongoPersistentEntityIndexCreatorは保存されたエンティティ クラスをスキャンして@Indexed注釈を探し、インデックスを作成します。ただし、次の式に基づいてコレクション名を検出します (ソースから):

String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();

注釈からのindex.collection()コレクションと@Indexed注釈entity.getCollection()からのコレクション@Documentです。

したがって、ensureIndex()手動で呼び出す必要があります。奇妙な振る舞いだ。ここでバグを開くことができると思います: DATAMONGO

編集:@Documentで注釈が付けられたすべてのクラスを返し、から始まる mongodb からすべてのコレクションを取得 する関数を作成できると思いますcars.<year>。次に、注釈が付けられたすべてのフィールドを分析し、その結果、コレクション リストを使用してこのフィールドを@Indexed呼び出すことができます。ensureIndex

于 2013-08-03T09:59:56.023 に答える
2

次の理由により、コレクション名を手動で指定できるようにする必要があります。

I need to ensure different subclasses of Car end up in the same collection
I would like to store each year's worth of Cars in a separate collection

@Document最初のステートメントについては、メタデータ アノテーションを使用して単一のコレクションを適用できます。

@Document(collection="cars")
class Car {

    @Id
    String id ;

    @Indexed
    String manufacturer ;

}

@Document(collection="cars")
class Honda extends Car {

}

@Document(collection="cars")
class Volvo extends Car {

}

のコレクション フィールドは、car のすべてのサブクラスが cars コレクションに取り込まれるように処理し、さらに注釈@Documentを使用してインデックスが自動的に作成されます。@Indexed

于 2013-08-03T18:27:24.503 に答える
0

長い間検索した結果、今のところ注釈を使用することはできないと思うので、このシナリオをプログラムで管理する方法を作成しました。

通常のインデックスと複合インデックスの作成

最初に、インデックス構造をマップするオブジェクトを定義しました。

public class CollectionDefinition {

private String id;
private String collectionName;
private LinkedHashMap<String, Sort.Direction> normalIndexMap;
private ArrayList<String> compoundIndexMap;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getCollectionName() {
    return collectionName;
}

public void setCollectionName(String collectionName) {
    this.collectionName = collectionName;
}

public LinkedHashMap<String, Sort.Direction> getNormalIndexMap() {
    return normalIndexMap;
}

public void setNormalIndexMap(LinkedHashMap<String, Sort.Direction> normalIndexMap) {
    this.normalIndexMap = normalIndexMap;
}

public ArrayList<String> getCompoundIndexMap() {
    return compoundIndexMap;
}

public void setCompoundIndexMap(ArrayList<String> compoundIndexMap) {
    this.compoundIndexMap = compoundIndexMap;
}

Json コレクションは次のようになります

{
"collectionName" : "example", 
"normalIndexMap" : {
    "sessionId" : "ASC", 
    "hash" : "DESC"
}, 
"compoundIndexMap" : [
    "{\"hash\":1,\"sessionId\":1,\"serverDate\":-1}", 
    "{\"sessionId\":1,\"serverDate\":-1}", 
    "{\"sessionId\":1,\"loginWasSuccessful\":1,\"loginDate\":-1}"
]}

次に、コレクションとインデックスを作成できます

private List<IndexDefinition> createIndexList(Map<String, Sort.Direction> normalIndexMap) {
    Set<String> keySet = normalIndexMap.keySet();
    List<IndexDefinition> indexArray = new ArrayList<>();
    for (String key : keySet) {
        indexArray.add(new Index(key, normalIndexMap.get(key)).background());
    }
    return indexArray;
}

結果の単一インデックス リストを使用して、単一フィールド インデックスを作成できます。

private void createIndexes(List<IndexDefinition> indexDefinitionList, MongoOperations mongoOperations, String collectionName) {
    indexDefinitionList.forEach(indexDefinition -> mongoOperations.indexOps(collectionName).ensureIndex(indexDefinition));
}

複合インデックスまたはマルチフィールド インデックスは扱いにくいです。インデックスを定義するには、DBObjects を作成する必要があります。

private List<DBObject> createCompountIndexList(List<String> compoundIndexStringMapList) {//NOSONAR IS IN USE
    if (compoundIndexStringMapList == null || compoundIndexStringMapList.isEmpty())
        return new ArrayList<>(); //NOSONAR
    ObjectMapper mapper = new ObjectMapper();
    List<DBObject> basicDBObjectList = new ArrayList<>();
    for (String stringMapList : compoundIndexStringMapList) {
        LinkedHashMap<String, Integer> parsedMap;
        try {
            parsedMap = mapper.readValue(stringMapList, new TypeReference<Map<String, Integer>>() {
            });
            BasicDBObjectBuilder dbObjectBuilder = BasicDBObjectBuilder.start();
            Iterator it = parsedMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry indexElement = (Map.Entry) it.next();
                dbObjectBuilder.add((String) indexElement.getKey(), indexElement.getValue());
                it.remove(); // avoids a ConcurrentModificationException
            }
            basicDBObjectList.add(dbObjectBuilder.get());
        } catch (IOException e) {//NOSONAR I´m logging it, we can not do anything more here cause it is part of the db configuration settings that need to be correct
            Logger.getLogger(JsonCollectionCreation.class).error("The compound index definition " + stringMapList + " is not correct it can not be mapped to LinkHashMap");
        }

    }
    return basicDBObjectList;
}

その結果を使用して、コレクション内にインデックスを作成できます

private void createCompoundIndex(List<DBObject> compoundIndexList, MongoOperations mongoOperations, String collectionName) {
    if (compoundIndexList.isEmpty()) return;
    for (DBObject compoundIndexDefinition : compoundIndexList) {
        mongoOperations.indexOps(collectionName).ensureIndex(new CompoundIndexDefinition(compoundIndexDefinition).background());
    }
}
于 2017-02-23T22:57:02.120 に答える