Fetch data from mongo db in spring boot application where collection name & fields to fetch are known at runtime

huangapple go评论97阅读模式
英文:

Fetch data from mongo db in spring boot application where collection name & fields to fetch are known at runtime

问题

我需要在Spring Boot批处理作业中创建一个任务,其中我需要从mongoDB获取数据,但我在编码时没有关于集合名称和要获取的字段的信息。只有当批处理开始时,我才会获得这些信息。
例如,当批处理开始时,我可以读取属性文件,在那里我可以通过一个属性获取集合名称,另一个属性给出要获取的字段列表,第三个字段为查询提供条件。

因此,由于这个原因,在编码时我不能定义一个Java POJO,其中包含集合的映射,也不能创建任何MongoRepository\Template(集合名称在运行时已知)。

我想知道的是,就像以前的原生SQL一样,如果我知道字段名和表名,那么可以动态生成SQL并执行以获取数据:

String dynamicQuery = "SELECT " + commaSeperatedFieldsList + " FROM " + tableName + " WHERE " + criteria;

在Spring Boot + MongoDB中是否有实现相同目标的方法呢?

英文:

I need to create a spring boot batch job in which, I need to fetch data from mongoDB where I don't have info about collection name & fields to fetch at coding time. I get this info only when the batch starts.
E.g. When batch starts, I can read properties file where I get collection name by 1 property & another property gives list of fields to fetch, third filed provides criteria/condition for query
So, due to this, I cant have a Java POJO defined which have mapping for collection or I cant create any MongoRepository\Template (collection name is known at runtime).

What I want to know is, just like plain old native SQL, if i get to know fields name & table name, on the fly, SQL can be build & can be fired to get the data:

String dynamicQuery = "SELECT " + commaSeperatedFieldsList + " FROM " + tableName + " WHERE " + criteria;

Is there any way by which same thing can be achieved in spring boot + mongo DB?

答案1

得分: 1

你可以使用MongoTemplate来实现这一点,它可以自动连接注入,因为Spring会自动为您提供并配置它。

它有一个方法:

find(Query query, Class<T> entityClass, String collectionName)

该方法允许您定义自定义的集合名称和自定义的entityClass。

对于动态查询,可以使用BasicQuery作为Query的实现,以传递原始的Mongo JSON查询,如果要限制返回的字段,则可以将字段/投影作为JSON传递。

使用org.bson.Document作为entityClass,它基本上是一个Map实现,允许您以动态的方式迭代字段。

mongoTemplate.find(new BasicQuery("{ name: \"mongodb\"}", "{ name: 1}"), Document.class, "your-collection-name").forEach(x -> {
    x.get("name"); // 访问特定字段

    x.forEach((key, value) -> {
        // 遍历所有字段
    });
});

当处理大量结果时,考虑使用MongoTemplatestream()方法,方式与上述类似,因为这不会一次性将所有文档加载到内存中,而是可以在执行期间逐个处理。

英文:

You can use MongoTemplate for this which can be autowired as spring provides and configures it for you automatically.

It has a

find(Query query, Class&lt;T&gt; entityClass, String collectionName)

method which lets you define a custom collection name and a custom entityClass.

For the dynamic query use BasicQuery as Query impl to pass a raw mongo json query and fields/projection as json if you want to limit the fields returned.

Use org.bson.Document as entityClass which is basically a Map implementation which lets you iterate over the fields in a dynamic manner.

mongoTemplate.find(new BasicQuery(&quot;{ name: \&quot;mongodb\&quot;}&quot;, &quot;{ name: 1}&quot;), Document.class, &quot;your-collection-name&quot;).forEach(x -&gt; {
    x.get(&quot;name&quot;); // access a specific field

    x.forEach((key, value) -&gt; {
        // iterate over all fields
    });
});

When you deal with a large result consider using MongoTemplate's stream() method in the same way as this doesn't load all documents into memory at once and you can process it during execution one by one.

huangapple
  • 本文由 发表于 2020年4月3日 20:49:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/61012311.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定