如何使用 Micronaut 在 mongoDB 中创建 TextFree 搜索

How to create a TextFree search in mongoDB with Micronaut

我正在使用响应式 MongoDb,并尝试根据权重实施自由文本搜索

implementation("io.micronaut.mongodb:micronaut-mongo-reactive")

在下面的 POJO

public class Product {
    @BsonProperty("_id")
    @BsonId
    private ObjectId id;
    private String name;
    private float price;
    private String description;
}

试过这个简单的例子

public Flowable<List<Product>> findByFreeText(String text) {
    LOG.info(String.format("Listener --> Listening value = %s", text));
    Flowable.fromPublisher(this.repository.getCollection("product", List.class)
            .find(new Document("$text", new Document("$search", text)
                    .append("$caseSensitive", false)
                    .append("$diacriticSensitive", false)))).subscribe(item -> {
                System.out.println(item);
            }, error -> {
                System.out.println(error);
            });
    return Flowable.just(List.of(new Product()));
}

我认为这不是实现自由文本搜索的正确方法。

一开始你不需要 FlowableListProduct,因为 Flowable 可以管理多个值,这与 Single 不同。所以,有Flowable<Product>就够了。然后你可以简单地 return 来自 find 方法的 Flowable 实例。

文本搜索可以这样实现:

public Flowable<Product> findByFreeText(final String query) {
    return Flowable.fromPublisher(repository.getCollection("product", Product.class)
        .find(new Document("$text",
            new Document("$search", query)
                .append("$caseSensitive", false)
                .append("$diacriticSensitive", false)
        )));
}

然后由方法的消费者决定如何订阅结果Flowable。在控制器中,您可以直接 return Flowable 实例。如果您需要在代码中的某处使用它,您可以执行 subscribe()blockingSubscribe() 等等。

您当然可以像这样通过 JUnit 对其进行测试:

@MicronautTest
class SomeServiceTest {
    @Inject
    SomeService service;

    @Test
    void findByFreeText() {
        service.findByFreeText("test")
            .test()
            .awaitCount(1)
            .assertNoErrors()
            .assertValue(p -> p.getName().contains("test"));
    }
}

更新: 您可以通过在 logback.xml 中设置来调试与 MongoDB 的通信(Micronaut 正在使用Logback 作为默认日志框架)日志配置文件:

<configuration>
    ....
    <logger name="org.mongodb" level="debug"/>
</configuration>

然后您将在日志文件中看到:

16:20:21.257 [Thread-5] DEBUG org.mongodb.driver.protocol.command - Sending command '{"find": "product", "filter": {"$text": {"$search": "test", "$caseSensitive": false, "$diacriticSensitive": false}}, "batchSize": 2147483647, "$db": "some-database"}' with request id 6 to database some-database on connection [connectionId{localValue:3, serverValue:1634}] to server localhost:27017
16:20:21.258 [Thread-8] DEBUG org.mongodb.driver.protocol.command - 16:20:21.258 [Thread-7] DEBUG org.mongodb.driver.protocol.command - Execution of command with request id 6 completed successfully in 2.11 ms on connection [connectionId{localValue:3, serverValue:1634}] to server localhost:27017

然后你可以从日志中复制命令并在 MongoDB CLI 中尝试,或者你可以安装 MongoDB Compass 在那里你可以更多地使用它并查看命令是否正确。