How can I convert collection.find to a json query in Java

In Java I am submitting a query as follows (where all of the params are Bson Documents)

		List<Document> results = collection.find(searchPredicate)
				.projection(projectionFields)
				.sort(sort)
				.skip(skip)
				.limit(limit)
				.into(new ArrayList<>());

I would like to convert that query to a Json string that can be executed in Compass
I tried:

Document fullQuery = new Document();
fullQuery.putAll(searchPredicate);
fullQuery.append($project, projectionFields);
fullQuery.append($sort, sort);
fullQuery.append($skip, skip);
fullQuery.append($limit, limit);
String queryJson = fullQuery.toJson();

But that does not execute in compass
What is the correct composition of documents?

I am not sure what you mean by

If what you mean is that you cut-n-paste the Java code in Compass and tried to execute it surely does not work. Compass does not understand Java code.

What could work is to cut-n-paste the result of printing queryJson. It also depends where and how you try to execute it in Compass.

And in understanding what you mean by

we would need more details on what is actually happening.

No, sorry that is not what I meant.
What I meant is that in our Java codebase, we have a Mongo query that looks like

		List<Document> results = collection.find(searchPredicate)
				.projection(projectionFields)
				.sort(sort)
				.skip(skip)
				.limit(limit)
				.into(new ArrayList<>());

Where all of the arrguments are Bson Documents

I want to add a diagnostic logging printout right after that Java call, to print out the Json equivalent of that “.find” call. The json should be such that if I pasted it as Json into the Compass aggregation tab, it would work as is. This would help me diagnose queries using compass instead of having to do it in Java.
I want to know how to construct that Json

Answered by

If you print queryJson, from

it should producer something that you could cut-n-paste and execute.

yes it should, but when I try to execute it, compass does not allow me to execute it, it requires more adjustment.

Here is the json it generates:

{
  "$match": {
    "$and": [
      {
        "$and": [
          {
            "name": "Joe"
          }
        ]
      }
    ]
  },
  "$project": {
    "fullName": true
  },
  "$sort": {
    "fullName": 1
  },
  "$skip": 0,
  "$limit": 100
}

Mongo compass complains with “Pipeline must be an array of aggregation stages”

I was hoping someone might have solved this

It does because your Java code is wrong.

As the error message indicate, the pipeline must be an array. With

you create a Document not an array. Try with

ArrayList<Document> fullQuery = new ArrayList<>();

and since each stage must be document rather than a field you should also change

to

There is nothing to solve, you just have to start with the correct code. Honestly, I have not looked in details to your code since I assumed that it was working.

And personally, I develop in JS and store the aggregation in a .json file. When I need to run it in Java I simply use Document.parse().

Maybe nothing to solve, but you mostly solved it, thanks!
But finally how do I convert that fullQuery ArrayList to Json???

With a little cheating

ArrayList fullQuery = new ArrayList<>();
...
Document array = new Document( "fullQuery" : fullQuery ) ;
String queryJson = array.toJson() ;

Then queryJson will look like

{ queryJson : [
    /* the pipeline stages */
] }

Nope, that returns this:

{
  "fullQuery": [
    {
      "$match": {
        "$and": [
          {
            "$and": [
              {
                "name": "joe"
              }
            ]
          }
        ]
      }
    },
    {
      "$project": {
         "fullName": true
  },
 {
  "$sort": {
       "fullName": 1
    },
    {
      "$skip": 0
    },
    {
      "$limit": 1
    }
  ]
}

Compass complains: Pipeline must be an array of aggregation stages

Yes, but the query is the value of fullQuery which start at the first [ and ends at the last ]. So it is

This works, thanks for the guidance:
queryJson = queryJson.replaceAll("\\{\"fullQuery\": (.+)}", "$1");
Would be nice if there were a way to get that directly, but beggars can’t be choosers!

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.