spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.59k stars 1.07k forks source link

Aggregation.stage() containing a compound search deletes the first entry #4737

Closed bjornharvold closed 3 days ago

bjornharvold commented 3 days ago

Hi Team Spring Data 🦸

Here's my compound $search operation:

final AggregationOperation searchOperation = Aggregation.stage("""
                            { $search : {
                                "compound": {
                                 "must": {
                                   "near": {
                                     "origin": {
                                       "type": "Point",
                                       "coordinates": [%s, %s]
                                     },
                                     "pivot": %s,
                                     "path": "inventory.location",
                                     "distanceField": "distanceInMeters",
                                   }
                                 },
                                 "must": {
                                   "text": {
                                     "query": "%s",
                                     "path": ["inventory.hotel.name", "inventory.inventoryName"]
                                   }
                                 }
                                }
                              }
                            }
                        """.formatted(latitude, longitude, radiusInMeters, phrases.getFirst()));

The aggregation operation object looks like this when executing ((BasicAggregationOperation) searchOperation).value():

{ 
  $search : {
    "compound": {
     "must": {
       "near": {
         "origin": {
           "type": "Point",
           "coordinates": [13.7370197, 100.5581533]
         },
         "pivot": 10000,
         "path": "inventory.location",
         "distanceField": "distanceInMeters",
       }
     },
     "must": {
       "text": {
         "query": "The Hotel",
         "path": ["inventory.hotel.name", "inventory.inventoryName"]
       }
     }
    }
  }
}

This operation gets added to a list of aggregation operations.

Example:

List<AggregationOperation> operations = new ArrayList<>();
operations.add(searchOperation);

final CountOperation countOperation = count().as("count");
operations.add(countOperation);

final Aggregation aggCount = newAggregation(operations);

When looking at the toString() pipeline from aggCount, it looks like this:

{
    "aggregate": "__collection__",
    "pipeline": [
        {
            "$search": {
                "compound": {
                    "must": {
                        "text": {
                            "path": [
                                "inventory.hotel.name",
                                "inventory.inventoryName"
                            ],
                            "query": "The Hotel"
                        }
                    }
                }
            }
        },
        {
            "$count": "count"
        }
    ]
}

The near operation was stripped out of the compound query.

bjornharvold commented 3 days ago

This issue is not within Spring Data. I get the same issue when running org.mongodb.bson.Document.parse().