MongoDB多个近距离查询

时间:2017-09-06 20:54:50

标签: mongodb geospatial

我正在尝试设计一个可以传递给MongoDB的查询,该查询可以有效地获取多个zipcodes的指定半径内的所有zipcodes。

例如,我会传递一个zipcodes列表(public class LinePagerIndicatorDecoration extends RecyclerView.ItemDecoration { private int colorActive = 0xFFFFFFFF; private int colorInactive = 0x66FFFFFF; private static final float DP = Resources.getSystem().getDisplayMetrics().density; /** * Height of the space the indicator takes up at the bottom of the view. */ private final int mIndicatorHeight = (int) (DP * 16); /** * Indicator stroke width. */ private final float mIndicatorStrokeWidth = DP * 2; /** * Indicator width. */ private final float mIndicatorItemLength = DP * 16; /** * Padding between indicators. */ private final float mIndicatorItemPadding = DP * 4; /** * Some more natural animation interpolation */ private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator(); private final Paint mPaint = new Paint(); public LinePagerIndicatorDecoration() { mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(mIndicatorStrokeWidth); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); int itemCount = parent.getAdapter().getItemCount(); // center horizontally, calculate width and subtract half from center float totalLength = mIndicatorItemLength * itemCount; float paddingBetweenItems = Math.max(0, itemCount - 1) * mIndicatorItemPadding; float indicatorTotalWidth = totalLength + paddingBetweenItems; float indicatorStartX = (parent.getWidth() - indicatorTotalWidth) / 2F; // center vertically in the allotted space float indicatorPosY = parent.getHeight() - mIndicatorHeight / 2F; drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount); // find active page (which should be highlighted) LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); int activePosition = layoutManager.findFirstVisibleItemPosition(); if (activePosition == RecyclerView.NO_POSITION) { return; } // find offset of active page (if the user is scrolling) final View activeChild = layoutManager.findViewByPosition(activePosition); int left = activeChild.getLeft(); int width = activeChild.getWidth(); // on swipe the active item will be positioned from [-width, 0] // interpolate offset for smooth animation float progress = mInterpolator.getInterpolation(left * -1 / (float) width); drawHighlights(c, indicatorStartX, indicatorPosY, activePosition, progress, itemCount); } private void drawInactiveIndicators(Canvas c, float indicatorStartX, float indicatorPosY, int itemCount) { mPaint.setColor(colorInactive); // width of item indicator including padding final float itemWidth = mIndicatorItemLength + mIndicatorItemPadding; float start = indicatorStartX; for (int i = 0; i < itemCount; i++) { // draw the line for every item c.drawLine(start, indicatorPosY, start + mIndicatorItemLength, indicatorPosY, mPaint); start += itemWidth; } } private void drawHighlights(Canvas c, float indicatorStartX, float indicatorPosY, int highlightPosition, float progress, int itemCount) { mPaint.setColor(colorActive); // width of item indicator including padding final float itemWidth = mIndicatorItemLength + mIndicatorItemPadding; if (progress == 0F) { // no swipe, draw a normal indicator float highlightStart = indicatorStartX + itemWidth * highlightPosition; c.drawLine(highlightStart, indicatorPosY, highlightStart + mIndicatorItemLength, indicatorPosY, mPaint); } else { float highlightStart = indicatorStartX + itemWidth * highlightPosition; // calculate partial highlight float partialLength = mIndicatorItemLength * progress; // draw the cut off highlight c.drawLine(highlightStart + partialLength, indicatorPosY, highlightStart + mIndicatorItemLength, indicatorPosY, mPaint); // draw the highlight overlapping to the next item as well if (highlightPosition < itemCount - 1) { highlightStart += itemWidth; c.drawLine(highlightStart, indicatorPosY, highlightStart + partialLength, indicatorPosY, mPaint); } } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.bottom = mIndicatorHeight; } } )和半径20km。响应将是落在该半径范围内的所有zipcode的列表。

以下是我的集合中的文档示例,其中["10001", "97201", "37208"]上有一个2dsphere索引。

loc

我不确定最佳解决方案是什么,甚至可以在一个查询/ map-reduce中实现。任何帮助将不胜感激。

0 个答案:

没有答案