c# mongodb как искать по идентификатору и фильтровать по массиву строк - PullRequest
1 голос
/ 21 апреля 2020

У меня есть объект, который выглядит следующим образом в моей базе данных

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

, когда кому-то нравится публикация, я пытаюсь запросить мой пост-объект по postId и проверить в массиве лайков userIds, если он содержит userId, тогда удалите этот идентификатор пользователя (не как) из массива или добавьте его (как) в массив, если его не существует. это то, что у меня так далеко, но это не работает, любая помощь?

 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);

но это не работает для меня thows исключений 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)

1 Ответ

0 голосов
/ 21 апреля 2020

Я исправил эту проблему, выполнив следующие действия:

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);
...