Markov
Markov

Reputation: 150

c# mongodb how to search by id and filter by array of string

I have an object that looks like this in my db

{
   "_id":{
      "$oid":"5e9de27a4f55601268115efd"
   },
   "UserId":"5e8f649853ed63a6bcf3b22c",
   "Picture":"/picture/123",
   "Name":"Test Post APi",
   "Body":"Testing api",
   "Likes":[
      "5e91f4a9839b426c8cc942b7",
      "5e91f4a98395e91f4a9839bs4",
      "5e91f4a98395e91f4a98332dg"
   ],
   "DatePosted":{
      "$date":{
         "$numberLong":"1587411900296"
      }
   }
}

when someone likes a post I am trying query my post object by postId and check in likes array of userIds if it contains the userId then remove that userid(un-like) from array or add it(like) to array if doesn't exists. these is what I haveso far but it doesnt work, any help?

 UpdateDefinition<Post> newPostValues;

var findId = Builders<Post>.Filter.Eq("_id", request.Id);
var findLike = Builders<Post>.Filter.ElemMatch(x => x.Likes, x => x == request.PostUserId);
var combineFilters = Builders<Post>.Filter.And(findId, findLike);

var post = await _context.Posts.Find(combineFilters).SingleOrDefaultAsync();

// set value to add like to post 
if (post == null)
{
    newPostValues = Builders<Post>.Update.Push(p => p.Likes, request.UserId);

}
// set new value to remove like from post
else
{
    newPostValues = Builders<Post>.Update.PullFilter(p => p.Likes,
                                                l => l == request.PostUserId);
}

var result = await _context.Posts.UpdateOneAsync(e => e.Id == request.Id, newPostValues);

but it doesnt work for me thows an exeptions System.InvalidOperationException: {document} is not supported.

System.InvalidOperationException: {document} is not supported.
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.GetFieldExpression(Expression expression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(Expression variableExpression, ExpressionType operatorType, ConstantExpression constantExpression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(BinaryExpression binaryExpression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate[TDocument](Expression`1 predicate, IBsonSerializer`1 parameterSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.ExpressionFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.ElementMatchFilterDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.AndFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
   at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass43_0`1.<FindAsync>b__0(IClientSessionHandle session)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.SingleOrDefaultAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)
   at Application.Posts.Like.Handler.Handle(Command request, CancellationToken cancellationToken) in C:\OwnDevelopment\ConnectPost\Application\Posts\Like.cs:line 42
   at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at API.Controllers.PostsController.Like(String Id, Command command) in C:\OwnDevelopment\ConnectPost\API\Controllers\PostsController.cs:line 45
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Upvotes: 1

Views: 2783

Answers (1)

Markov
Markov

Reputation: 150

I have fixed this issue by doing the following

var post = await _context.Posts.Find(x => x.Id == request.Id).SingleOrDefaultAsync();

// add/remove likes from post
var newLikeValue = post.Likes.Contains(request.UserId) ? Builders<Post>.Update.Pull(p => p.Likes, request.UserId) : Builders<Post>.Update.Push(p => p.Likes, request.UserId);

var result = await _context.Posts.UpdateOneAsync(e => e.Id == request.Id, newLikeValue);

Upvotes: 1

Related Questions