Sunday, 29 November 2020

Mongoose: How to get documents that their subdocument includes a value ( Many to one relationship )

I have a situation that i need to filter users based on their Profession, here is how the User Schema is defined:

const userSchema = new mongoose.Schema(
  {
    userData: {
      professions: [
        {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'Profession'
        }
      ]
    }
  }
)

and here we have for Professions schema:

const ProfessionSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: true,
      trim: true,
    }
  }
)

How can I get a list of users that have a profession with an id of 5f8ea4396586f1168ab3a298 for example?

I tried

User.find({
    "userData.professions": { $elemMatch: $in: ["5f8ea4396586f1168ab3a298"] }
})

But seems like this is the opposite of what I'm trying to do. I need to get a result like this when I filter results based on 5f8ea4396586f1168ab3a298 as id of profession

[
    {
        "name": "John Doe",
        "userData": {
            "professions": ["5f8ea4396586f1168ab3a298", "5f8ea4226586f1168ab3a296"]
        }
    },
    {
        "name": "John Smith",
        "userData": {
            "professions": ["5f8ea4396586f1168ab3a298",]
        }
    },
    {
        "name": "Elon Musk",
        "userData": {
            "professions": ["5f8ea4466586f1168ab3a29a", "5f8ea4396586f1168ab3a298", "5f8ea4146586f1168ab3a295"]
        }
    }
]


from Mongoose: How to get documents that their subdocument includes a value ( Many to one relationship )

Async gRCP server with maximum_concurrent_rpcs limitation raises an exception

I tried to implement gRPC server with gRPC AsyncIO API. I used this example as a sample and tried to define maximum_concurrent_rpcs limitation on server as described in source code documentation in gRPC AsyncIO server source code. Here is my implementation:

import asyncio
from grpc.experimental import aio

import helloworld_pb2
import helloworld_pb2_grpc


class Greeter(helloworld_pb2_grpc.GreeterServicer):

    async def SayHello(self, request, context):
        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)


async def serve():
    server = aio.server(maximum_concurrent_rpcs = 10)
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    listen_addr = '[::]:50051'
    server.add_insecure_port(listen_addr)
    logging.info("Starting server on %s", listen_addr)
    await server.start()
    await server.wait_for_termination()


if __name__ == '__main__':
    asyncio.run(serve())

But it raises the following exception:

AttributeError: 'Server' object has no attribute '_server'

My question is, how is it possible to define gRPC AsyncIO server with maximum_concurrent_rpcs limitation.

Note that helloworld_pb2 and helloworld_pb2_grpc are available in this repositroy



from Async gRCP server with maximum_concurrent_rpcs limitation raises an exception

Walk along 2D numpy array as long as values remain the same

Short description
I want to walk along a numpy 2D array starting from different points in specified directions (either 1 or -1) until a column changes (see below)

Current code

First let's generate a dataset:

# Generate big random dataset
# first column is id and second one is a number
np.random.seed(123)
c1 = np.random.randint(0,100,size = 1000000)
c2 = np.random.randint(0,20,size = 1000000)
c3 = np.random.choice([1,-1],1000000 )
m = np.vstack((c1, c2, c3)).T
m = m[m[:,0].argsort()]

Then I wrote the following code that starts at specific rows in the matrix (start_points) then keeps extending in the specified direction (direction_array) until the metadata changes:

 def walk(mat, start_array):
    start_mat       = mat[start_array]
    metadata        = start_mat[:,1]
    direction_array = start_mat[:,2]
    walk_array      = start_array
    
    while True:
        walk_array = np.add(walk_array, direction_array)
        try:
            walk_mat = mat[walk_array]
            walk_metadata = walk_mat[:,1]
            if sorted(metadata) != sorted(walk_metadata):
                raise IndexError
        except IndexError:
            return  start_mat, mat[walk_array + (direction_array *-1)]
            
s = time.time()
for i in range(100000):
    start_points = np.random.randint(0,1000000,size = 3)
    res = walk(m, start_points)

Question
While the above code works fine I think there must be an easier/more elegant way to walk along a numpy 2D array from different start points until the value of another column changes? This for example requires me to slice the input array for every step in the while loop which seems quite inefficient (especially when I have to run walk millions of times).



from Walk along 2D numpy array as long as values remain the same