如何向RethinkDB的Filter内部函数传递多个参数
Got it, let's break down how to handle this RethinkDB scenario where you need to compare and merge properties across multiple client documents.
First, a quick clarification: RethinkDB's filter() method natively only passes the current document being iterated as a parameter. But to work with "multiple parameters" (i.e., compare the current document against other matching documents), we can nest table queries inside the filter/map callback to fetch and reference other client data.
Core Approach
- Traverse all client documents using
map()(since you want to retain all clients and add merged properties,map()is more suitable than justfilter()). - For each current document, query the table again to find other clients that meet your filter conditions.
- Merge the properties of those matching clients into the current document's attributes.
Example Implementation
Let's use your data structure and a concrete example: suppose we want to get every client, and attach a list of other clients whose latitude (coords.lat) is within 50 units of the current client's latitude.
Your data structure:
{ "client": { "name": "andrew", "coords": {"lat": 200, "long": 300} } }
Here's the RethinkDB query code:
r.table("clients") .map(function(currentDoc) { // Extract the current client's data const currentClient = currentDoc("client"); // Query for other clients that meet our filter criteria const matchingClients = r.table("clients") .filter(function(otherDoc) { const otherClient = otherDoc("client"); // Filter rules: not the current client, and latitude difference < 50 return r.and( otherClient("name").ne(currentClient("name")), otherClient("coords")("lat").sub(currentClient("coords")("lat")).abs().lt(50) ); }) .pluck("client", "name") // Only grab the name property we need .map(function(doc) { return doc("client")("name"); }) .coerceTo("array"); // Convert the cursor to an array of names // Merge the current client data with the list of matching client names return currentClient.merge({ nearby_clients: matchingClients }); });
Key Notes
- Use
map()for transformation: Since your goal is to keep all clients and add merged properties,map()is better thanfilter()alone (you can add afilter()beforemap()if you first need to narrow down the base client list). - Nested queries for multi-document comparison: By re-querying the table inside the callback, you effectively get access to "other documents" as additional parameters to work with.
merge()for property combining: RethinkDB'smerge()method seamlessly combines the original client attributes with the new merged data (like the list of nearby clients here).
Adjust the inner filter() logic to match your specific conditions (e.g., longitude ranges, other client attributes) and modify the merge() step to include whatever properties you want to combine.
内容的提问来源于stack exchange,提问作者Bercovici Adrian

